ring.c
资源名称:c.rar [点击查看]
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:4k
源码类别:

VC书籍

开发平台:

C/C++

  1. static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/ring.doc,v 1.12 1997/02/21 19:49:24 drh Exp $";
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include "assert.h"
  6. #include "ring.h"
  7. #include "mem.h"
  8. #define T Ring_T
  9. struct T {
  10. struct node {
  11. struct node *llink, *rlink;
  12. void *value;
  13. } *head;
  14. int length;
  15. };
  16. T Ring_new(void) {
  17. T ring;
  18. NEW0(ring);
  19. ring->head = NULL;
  20. return ring;
  21. }
  22. T Ring_ring(void *x, ...) {
  23. va_list ap;
  24. T ring = Ring_new();
  25. va_start(ap, x);
  26. for ( ; x; x = va_arg(ap, void *))
  27. Ring_addhi(ring, x);
  28. va_end(ap);
  29. return ring;
  30. }
  31. void Ring_free(T *ring) {
  32. struct node *p, *q;
  33. assert(ring && *ring);
  34. if ((p = (*ring)->head) != NULL) {
  35. int n = (*ring)->length;
  36. for ( ; n-- > 0; p = q) {
  37. q = p->rlink;
  38. FREE(p);
  39. }
  40. }
  41. FREE(*ring);
  42. }
  43. int Ring_length(T ring) {
  44. assert(ring);
  45. return ring->length;
  46. }
  47. void *Ring_get(T ring, int i) {
  48. struct node *q;
  49. assert(ring);
  50. assert(i >= 0 && i < ring->length);
  51. {
  52. int n;
  53. q = ring->head;
  54. if (i <= ring->length/2)
  55. for (n = i; n-- > 0; )
  56. q = q->rlink;
  57. else
  58. for (n = ring->length - i; n-- > 0; )
  59. q = q->llink;
  60. }
  61. return q->value;
  62. }
  63. void *Ring_put(T ring, int i, void *x) {
  64. struct node *q;
  65. void *prev;
  66. assert(ring);
  67. assert(i >= 0 && i < ring->length);
  68. {
  69. int n;
  70. q = ring->head;
  71. if (i <= ring->length/2)
  72. for (n = i; n-- > 0; )
  73. q = q->rlink;
  74. else
  75. for (n = ring->length - i; n-- > 0; )
  76. q = q->llink;
  77. }
  78. prev = q->value;
  79. q->value = x;
  80. return prev;
  81. }
  82. void *Ring_addhi(T ring, void *x) {
  83. struct node *p, *q;
  84. assert(ring);
  85. NEW(p);
  86. if ((q = ring->head) != NULL)
  87. {
  88. p->llink = q->llink;
  89. q->llink->rlink = p;
  90. p->rlink = q;
  91. q->llink = p;
  92. }
  93. else
  94. ring->head = p->llink = p->rlink = p;
  95. ring->length++;
  96. return p->value = x;
  97. }
  98. void *Ring_addlo(T ring, void *x) {
  99. assert(ring);
  100. Ring_addhi(ring, x);
  101. ring->head = ring->head->llink;
  102. return x;
  103. }
  104. void *Ring_add(T ring, int pos, void *x) {
  105. assert(ring);
  106. assert(pos >= -ring->length && pos<=ring->length+1);
  107. if (pos == 1 || pos == -ring->length)
  108. return Ring_addlo(ring, x);
  109. else if (pos == 0 || pos == ring->length + 1)
  110. return Ring_addhi(ring, x);
  111. else {
  112. struct node *p, *q;
  113. int i = pos < 0 ? pos + ring->length : pos - 1;
  114. {
  115. int n;
  116. q = ring->head;
  117. if (i <= ring->length/2)
  118. for (n = i; n-- > 0; )
  119. q = q->rlink;
  120. else
  121. for (n = ring->length - i; n-- > 0; )
  122. q = q->llink;
  123. }
  124. NEW(p);
  125. {
  126. p->llink = q->llink;
  127. q->llink->rlink = p;
  128. p->rlink = q;
  129. q->llink = p;
  130. }
  131. ring->length++;
  132. return p->value = x;
  133. }
  134. }
  135. void *Ring_remove(T ring, int i) {
  136. void *x;
  137. struct node *q;
  138. assert(ring);
  139. assert(ring->length > 0);
  140. assert(i >= 0 && i < ring->length);
  141. {
  142. int n;
  143. q = ring->head;
  144. if (i <= ring->length/2)
  145. for (n = i; n-- > 0; )
  146. q = q->rlink;
  147. else
  148. for (n = ring->length - i; n-- > 0; )
  149. q = q->llink;
  150. }
  151. if (i == 0)
  152. ring->head = ring->head->rlink;
  153. x = q->value;
  154. q->llink->rlink = q->rlink;
  155. q->rlink->llink = q->llink;
  156. FREE(q);
  157. if (--ring->length == 0)
  158. ring->head = NULL;
  159. return x;
  160. }
  161. void *Ring_remhi(T ring) {
  162. void *x;
  163. struct node *q;
  164. assert(ring);
  165. assert(ring->length > 0);
  166. q = ring->head->llink;
  167. x = q->value;
  168. q->llink->rlink = q->rlink;
  169. q->rlink->llink = q->llink;
  170. FREE(q);
  171. if (--ring->length == 0)
  172. ring->head = NULL;
  173. return x;
  174. }
  175. void *Ring_remlo(T ring) {
  176. assert(ring);
  177. assert(ring->length > 0);
  178. ring->head = ring->head->rlink;
  179. return Ring_remhi(ring);
  180. }
  181. void Ring_rotate(T ring, int n) {
  182. struct node *q;
  183. int i;
  184. assert(ring);
  185. assert(n >= -ring->length && n <= ring->length);
  186. if (n >= 0)
  187. i = n%ring->length;
  188. else
  189. i = n + ring->length;
  190. {
  191. int n;
  192. q = ring->head;
  193. if (i <= ring->length/2)
  194. for (n = i; n-- > 0; )
  195. q = q->rlink;
  196. else
  197. for (n = ring->length - i; n-- > 0; )
  198. q = q->llink;
  199. }
  200. ring->head = q;
  201. }