1、A ring is much like a sequence: It holds N values associated with the integer indices zero through N −1 when N is positive.
2、An empty ring holds no values. Values are pointers.
3、Like the values in a sequence, values in a ring may be accessed by indexing.
4、Unlike a sequence, however, values can be added to a ring anywhere , and any value in a ring can be removed. 5、In addition, the values can be renumbered: “rotating” a ring left decrements the index of each value by one modulo the length of the ring; rotating it right increments the indi-ces by one modulo the ring length.
6、The price for the flexibility of adding values to and removing values from arbitrary locations in a ring is that accessing the i th value is not guaranteed to take constant time.
简单而言,ring就是一个“环”,底层用“双向链表”进行实现。
在环中的位置定义:
一个带有六个元素的示意图:
插入一个新结点的示意图:
删除结点的示意图:
=========================ring.h=========================
#ifndef RING_INCLUDED #define RING_INCLUDED #define T Ring_T typedef struct T *T; //exported functions extern T Ring_new (void); extern T Ring_ring (void *x, ...); extern void Ring_free (T *ring); extern int Ring_length(T ring); extern void *Ring_get (T ring, int i); extern void *Ring_put (T ring, int i, void *x); extern void *Ring_add (T ring, int pos, void *x); extern void *Ring_addlo (T ring, void *x); extern void *Ring_addhi (T ring, void *x); extern void *Ring_remove(T ring, int i); extern void *Ring_remlo (T ring); extern void *Ring_remhi (T ring); extern void Ring_rotate(T ring, int n); #undef T #endif
#include <stdlib.h> #include <stdarg.h> #include <string.h> #include "assert.h" #include "ring.h" #include "mem.h" #define T Ring_T struct T{ struct node{ struct node *llink, *rlink; void *value; } *head; int length; }; //functions T Ring_new(void){ T ring; NEW0(ring); ring->head = NULL; return ring; } T Ring_ring(void *x, ...){ va_list ap; T ring = Ring_new(); va_start(ap, x); for(; x; x = va_arg(ap, void *)) Ring_addhi(ring, x); va_end(ap); return ring; } void Ring_free(T *ring){ struct node *p, *q; assert(ring && *ring); if((p = (*ring)->head) != NULL){ int n = (*ring)->length; for(; n-- > 0; p = q){ q = p->rlink; FREE(p); } } FREE(*ring); } int Ring_length(T ring){ assert(ring); return ring->length; } void *Ring_get(T ring, int i){ struct node *q; assert(ring); assert(i >= 0 && i < ring->length); //q <- ith node { int n; q = ring->head; if(i < ring->length/2){ for(n = i; n-- > 0; ) q = q->rlink; }else{ for(n = ring->length - i; n-- > 0; ) q = q->llink; } } return q->value; } void *Ring_put(T ring, int i, void *x){ struct node *q; void *prev; assert(ring); assert(i >= 0 && i < ring->length); //q <- ith node { int n; q = ring->head; if(i <= ring->length/2){ for(n = i; n-- > 0; ) q = q->rlink; }else{ for(n = ring->length - i; n-- > 0; ) q = q->llink; } } prev = q->value; q->value = x; return prev; } void *Ring_addhi(T ring, void *x){ struct node *p, *q; assert(ring); NEW(p); if((q = ring->head) != NULL){ p->llink = q->llink; q->llink->rlink = p; p->rlink = q; q->llink = p; }else{ ring->head = p->llink = p->rlink = p; } ring->length++; return p->value = x; } void *Ring_addlo(T ring, void *x){ assert(ring); Ring_addhi(ring, x); ring->head = ring->head->llink; return x; } void *Ring_add(T ring, int pos, void *x){ assert(ring); assert(pos >= -ring->length && pos <= ring->length+1); if(pos == 1 || pos == -ring->length) return Ring_addlo(ring, x); else if(pos == 0 || pos == ring->length + 1) return Ring_addhi(ring, x); else{ struct node *p, *q; int i = pos < 0 ? pos + ring->length : pos - 1; //q <- ith node { int n; q = ring->head; if(i <= ring->length/2){ for(n = i; n-- > 0; ) q = q->rlink; }else{ for(n = ring->length - i; n-- > 0; ) q = q->llink; } } NEW(p); //insert p to the left of q { p->llink = q->llink; q->llink->rlink = p; p->rlink = q; q->llink = p; } ring->length++; return p->value = x; } } void *Ring_remove(T ring, int i){ void *x; struct node *q; assert(ring); assert(ring->length > 0); assert(i >= 0 && i < ring->length); //q <- ith node if(i == 0) ring->head = ring->head->rlink; x = q->value; //delete node q q->llink->rlink = q->rlink; q->rlink->llink = q->llink; FREE(q); if(--ring->length == 0) ring->head = NULL; return x; } void *Ring_remhi(T ring){ void *x; struct node *q; assert(ring); assert(ring->length > 0); q = ring->head->llink; x = q->value; //delete node q q->llink->rlink = q->rlink; q->rlink->llink = q->llink; FREE(q); if(--ring->length == 0) ring->head = NULL; return x; } void *Ring_remlo(T ring){ assert(ring); assert(ring->length > 0); ring->head = ring->head->rlink; return Ring_remhi(ring); } void Ring_rotate(T ring, int n){ struct node *q; int i; assert(ring); assert(n >= -ring->length && n <= ring->length); if(n >= 0) i = n%ring->length; else i = n + ring->length; //q <- ith node { int n; q = ring->head; if( i <= ring->length/2){ for(n = i; n-- > 0; ) q = q->rlink; }else{ for(n = ring->length - i; n-- > 0; ) q = q->llink; } } ring->head = q; }