splay.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:3k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: splay.c,v 1.10 1998/09/23 17:14:23 wessels Exp $
  3.  */
  4. #include "config.h"
  5. #if HAVE_STDIO_H
  6. #include <stdio.h>
  7. #endif
  8. #if HAVE_STDLIB_H
  9. #include <stdlib.h>
  10. #endif
  11. #if HAVE_UNISTD_H
  12. #include <unistd.h>
  13. #endif
  14. #include "splay.h"
  15. #include "util.h"
  16. int splayLastResult = 0;
  17. splayNode *
  18. splay_insert(void *data, splayNode * top, SPLAYCMP * compare)
  19. {
  20.     splayNode *new = xcalloc(sizeof(splayNode), 1);
  21.     new->data = data;
  22.     if (top == NULL) {
  23. new->left = new->right = NULL;
  24. return new;
  25.     }
  26.     top = splay_splay(data, top, compare);
  27.     if (splayLastResult < 0) {
  28. new->left = top->left;
  29. new->right = top;
  30. top->left = NULL;
  31. return new;
  32.     } else if (splayLastResult > 0) {
  33. new->right = top->right;
  34. new->left = top;
  35. top->right = NULL;
  36. return new;
  37.     } else {
  38. /* duplicate entry */
  39. xfree(new);
  40. return top;
  41.     }
  42. }
  43. splayNode *
  44. splay_splay(const void *data, splayNode * top, SPLAYCMP * compare)
  45. {
  46.     splayNode N;
  47.     splayNode *l;
  48.     splayNode *r;
  49.     splayNode *y;
  50.     if (top == NULL)
  51. return top;
  52.     N.left = N.right = NULL;
  53.     l = r = &N;
  54.     for (;;) {
  55. splayLastResult = compare(data, top);
  56. if (splayLastResult < 0) {
  57.     if (top->left == NULL)
  58. break;
  59.     if ((splayLastResult = compare(data, top->left)) < 0) {
  60. y = top->left; /* rotate right */
  61. top->left = y->right;
  62. y->right = top;
  63. top = y;
  64. if (top->left == NULL)
  65.     break;
  66.     }
  67.     r->left = top; /* link right */
  68.     r = top;
  69.     top = top->left;
  70. } else if (splayLastResult > 0) {
  71.     if (top->right == NULL)
  72. break;
  73.     if ((splayLastResult = compare(data, top->right)) > 0) {
  74. y = top->right; /* rotate left */
  75. top->right = y->left;
  76. y->left = top;
  77. top = y;
  78. if (top->right == NULL)
  79.     break;
  80.     }
  81.     l->right = top; /* link left */
  82.     l = top;
  83.     top = top->right;
  84. } else {
  85.     break;
  86. }
  87.     }
  88.     l->right = top->left; /* assemble */
  89.     r->left = top->right;
  90.     top->left = N.right;
  91.     top->right = N.left;
  92.     return top;
  93. }
  94. void
  95. splay_destroy(splayNode * top, SPLAYFREE *free_func)
  96. {
  97.     if (top->left)
  98. splay_destroy(top->left, free_func);
  99.     if (top->right)
  100. splay_destroy(top->right, free_func);
  101.     free_func(top->data);
  102.     xfree(top);
  103. }
  104. void
  105. splay_walk(splayNode *top, SPLAYWALKEE *walkee, void *state)
  106. {
  107.     if (top->left)
  108. splay_walk(top->left, walkee, state);
  109.     if (top->right)
  110. splay_walk(top->right, walkee, state);
  111.     walkee(top->data, state);
  112. }
  113. #ifdef DRIVER
  114. void
  115. splay_print(splayNode * top, void (*printfunc) ())
  116. {
  117.     if (top == NULL)
  118. return;
  119.     splay_print(top->left, printfunc);
  120.     printfunc(top->data);
  121.     splay_print(top->right, printfunc);
  122. }
  123. typedef struct {
  124.     int i;
  125. } intnode;
  126. int
  127. compareint(void *a, splayNode * n)
  128. {
  129.     intnode *A = a;
  130.     intnode *B = n->data;
  131.     return A->i - B->i;
  132. }
  133. void
  134. printint(void *a)
  135. {
  136.     intnode *A = a;
  137.     printf("%dn", A->i);
  138. }
  139. main(int argc, char *argv[])
  140. {
  141.     int i;
  142.     intnode *I;
  143.     splayNode *top = NULL;
  144.     srandom(time(NULL));
  145.     for (i = 0; i < 100; i++) {
  146. I = xcalloc(sizeof(intnode), 1);
  147. I->i = random();
  148. top = splay_insert(I, top, compareint);
  149.     }
  150.     splay_print(top, printint);
  151.     return 0;
  152. }
  153. #endif /* DRIVER */