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