scripts: move mega-sena in
[lcapit-junk-code.git] / CEP / C / mod_aa.c
bloba0ffabaedb58e54bac4408f75bfcd2f2f031c86b
1 #include <stdio.h>
2 #include <stdlib.h>
4 #include "misc.h"
5 #include "module.h"
6 #include "mod_aa.h"
8 struct node {
9 void *data;
10 int level;
11 struct node *left;
12 struct node *right;
15 struct aa_tree {
16 int size;
17 struct node *root;
18 int (*compare)(const void *key1, const void *key2);
19 void (*destroy)(void *data);
20 void (*dump)(const void *data);
23 static struct aa_tree cep_aa_tree;
25 static struct node *aa_node_alloc(void *data)
27 struct node *new;
29 new = malloc(sizeof(*new));
30 if (!new)
31 fatal("Could not allocate memory");
33 new->data = data;
34 new->left = new->right = NULL;
35 new->level = 1;
37 return new;
40 static struct node *skew(struct node *node)
42 struct node *left;
44 if (!node || !node->left || !node->left->right)
45 goto out;
47 if (node->left->level == node->level) {
49 * Swap the pointers of horizontal left
50 * links.
53 left = node->left;
54 node->left = left->right;
55 left->right = node;
57 return left;
60 out:
61 return node;
64 static struct node *split(struct node *node)
66 struct node *right;
68 if (!node || !node->right ||
69 !node->right->right || !node->right->left)
70 goto out;
72 if (node->level == node->right->right->level) {
74 * We have three horizontal right links.
75 * Take the middle element, elevate it, and return
76 * that.
79 right = node->right;
80 node->right = right->left;
81 right->left = node;
82 right->level++;
84 return right;
87 out:
88 return node;
91 static struct node *__aa_insert(void *data, struct node *node)
93 int cmpval;
95 if (!node)
96 return aa_node_alloc(data);
98 cmpval = cep_aa_tree.compare(data, node->data);
99 if (cmpval < 0) {
100 /* move to the left */
101 node->left = __aa_insert(data, node->left);
102 } else if (cmpval > 0) {
103 /* move to the right */
104 node->right = __aa_insert(data, node->right);
105 } else {
106 /* duplicated, just ignore it */
107 goto out;
110 node = skew(node);
111 node = split(node);
113 out:
114 return node;
117 static void aa_insert(void *data)
119 cep_aa_tree.root = __aa_insert(data, cep_aa_tree.root);
120 cep_aa_tree.size++;
123 static void *lookup(const void *data, struct node *node)
125 void *ret;
126 int cmpval;
128 if (!node) {
129 /* not found */
130 return NULL;
133 cmpval = cep_aa_tree.compare(data, node->data);
134 if (cmpval < 0) {
135 /* move to the left */
136 ret = lookup(data, node->left);
137 } else if (cmpval > 0) {
138 /* move to the right */
139 ret = lookup(data, node->right);
140 } else {
141 /* found */
142 ret = node->data;
145 return ret;
148 static void *aa_lookup(const void *data)
150 return lookup(data, cep_aa_tree.root);
153 static void aa_init(int (*compare)(const void *key1, const void *key2),
154 void (*destroy)(void *data),
155 void (*dump)(const void *data))
158 cep_aa_tree.size = 0;
159 cep_aa_tree.root = NULL;
160 cep_aa_tree.compare = compare;
161 cep_aa_tree.destroy = destroy;
162 cep_aa_tree.dump = dump;
165 static size_t aa_size(void)
167 return cep_aa_tree.size;
170 static void dump(struct node *node)
172 if (!node)
173 return;
175 dump(node->left);
177 cep_aa_tree.dump(node->data);
179 dump(node->right);
182 static void aa_dump(void)
184 dump(cep_aa_tree.root);
187 static void destroy(struct node *node)
189 if (!node)
190 return;
192 destroy(node->left);
193 destroy(node->right);
195 cep_aa_tree.destroy(node->data);
196 free(node);
199 static void aa_destroy(void)
201 destroy(cep_aa_tree.root);
204 struct module aa_module = {
205 .mod_name = "AA TREE",
206 .mod_init = aa_init,
207 .mod_destroy = aa_destroy,
208 .mod_insert = aa_insert,
209 .mod_lookup = aa_lookup,
210 .mod_dump = aa_dump,
211 .mod_size = aa_size,