Advertisement
cd62131

AA tree

Jan 29th, 2014
638
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.56 KB | None | 0 0
  1. #include <stdbool.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. typedef struct node node_t;
  6. struct node {
  7.   char *name;
  8.   char *number;
  9.   node_t *left;
  10.   node_t *right;
  11.   int level;
  12. };
  13. node_t *new_node(const char *name, const char *number) {
  14.   node_t *new = (node_t *) malloc(sizeof(node_t));
  15.   new->name = (char *) malloc(20);
  16.   new->number = (char *) malloc(12);
  17.   strcpy(new->name, name);
  18.   strcpy(new->number, number);
  19.   new->left = new->right = NULL;
  20.   new->level = 1;
  21.   return new;
  22. }
  23. node_t *skew(node_t *p) {
  24.   if (!p) return NULL;
  25.   if (!p->left) return p;
  26.   if (p->level != p->left->level) return p;
  27.   node_t *left = p->left;
  28.   p->left = left->right;
  29.   left->right = p;
  30.   return left;
  31. }
  32. node_t *split(node_t *p) {
  33.   if (!p) return NULL;
  34.   if (!p->right) return p;
  35.   if (!p->right->right) return p;
  36.   if (p->level != p->right->right->level) return p;
  37.   node_t *right = p->right;
  38.   p->right = right->left;
  39.   right->left = p;
  40.   right->level++;
  41.   return right;
  42. }
  43. node_t *insert(node_t *p, const char *name, const char *number) {
  44.   if (!p) return new_node(name, number);
  45.   int compare = strcmp(p->name, name);
  46.   if (compare < 0) p->left = insert(p->left, name, number);
  47.   else if (compare > 0) p->right = insert(p->right, name, number);
  48.   p = skew(p);
  49.   p = split(p);
  50.   return p;
  51. }
  52. bool leaf(node_t *p) {
  53.   return !p->right && !p->left;
  54. }
  55. node_t *successor(node_t *p) {
  56.   node_t *t = p->right;
  57.   if (!t) return NULL;
  58.   if (!t->left) return t;
  59.   for (t = t->left; !t && !t->left; t = t->left)
  60.     ;
  61.   return t;
  62. }
  63. node_t *predecessor(node_t *p) {
  64.   node_t *t = p->left;
  65.   if (!t) return NULL;
  66.   if (!t->right) return t;
  67.   for (t = t->right; !t && !t->right; t = t->right)
  68.     ;
  69.   return t;
  70. }
  71. int level(node_t *p) {
  72.   if (!p) return 0;
  73.   return p->level;
  74. }
  75. node_t *decrease_level(node_t *p) {
  76.   if (leaf(p)) {
  77.     p->level = 1;
  78.     return p;
  79.   }
  80.   if (!p->left) return p;
  81.   if (!p->right) return p;
  82.   if (leaf(p->left)) p->left->level = 1;
  83.   int min = level(p->left);
  84.   if (leaf(p->right)) p->right->level = 1;
  85.   if (min > level(p->right)) min = level(p->right);
  86.   min++;
  87.   if (min < level(p)) {
  88.     p->level = min;
  89.     if (min < level(p->right)) p->right->level = min;
  90.   }
  91.   return p;
  92. }
  93. node_t *delete(node_t *p, const char *name) {
  94.   if (!p) return NULL;
  95.   int compare = strcmp(p->name, name);
  96.   if (compare > 0) p->right = delete(p->right, name);
  97.   else if (compare < 0) p->left = delete(p->left, name);
  98.   else {
  99.     if (leaf(p)) return NULL;
  100.     else if (!p->left) {
  101.       node_t *t = successor(p);
  102.       char *name = t->name;
  103.       char *number = t->number;
  104.       p->right = delete(p->right, t->name);
  105.       p->name = name;
  106.       p->number = number;
  107.     }
  108.     else {
  109.       node_t *t = predecessor(p);
  110.       char *name = t->name;
  111.       char *number = t->number;
  112.       p->left = delete(p->left, t->name);
  113.       p->name = name;
  114.       p->number = number;
  115.     }
  116.   }
  117.   p = decrease_level(p);
  118.   p = skew(p);
  119.   if (!p) return NULL;
  120.   if (!p->right) return p;
  121.   p->right = skew(p->right);
  122.   if (!p->right->right) return p;
  123.   p->right->right = skew(p->right->right);
  124.   p = split(p);
  125.   p->right = split(p->right);
  126.   return p;
  127. }
  128. void print_tree(node_t *p) {
  129.   if (!p) {
  130.     puts("NULL");
  131.     return;
  132.   }
  133.   if (p->left) print_tree(p->left);
  134.   for (int i = 0; i < p->level - 1; i++)
  135.     printf("\t");
  136.   printf("%s %s %d\n", p->name, p->number, p->level);
  137.   if (p->right) print_tree(p->right);
  138. }
  139. node_t *search(node_t *p, const char *name) {
  140.   if (!p) return NULL;
  141.   int compare = strcmp(p->name, name);
  142.   if (compare > 0) return search(p->right, name);
  143.   else if (compare < 0) return search(p->left, name);
  144.   return p;
  145. }
  146. void search_g(node_t *p) {
  147.   puts("Search g");
  148.   node_t *found = search(p, "g");
  149.   if (found) puts("Found g");
  150.   else puts("Not Found g");
  151.   puts("----");
  152. }
  153. node_t *delete_and_print(node_t *p, const char *name) {
  154.   printf("Delete %s\n", name);
  155.   node_t *t = delete(p, name);
  156.   print_tree(t);
  157.   puts("----");
  158.   return t;
  159. }
  160. int main(void) {
  161.   char name[20];
  162.   char number[12];
  163.   char buf[BUFSIZ];
  164.   node_t *root = NULL;
  165.   FILE *in = fopen("dat", "r");
  166.   while (fgets(buf, BUFSIZ, in) != NULL) {
  167.     sscanf(buf, "%19s %11s", name, number);
  168.     printf("Insert %s\n", name);
  169.     root = insert(root, name, number);
  170.     print_tree(root);
  171.     puts("----");
  172.   }
  173.   const char * const e[] = { "a", "b", "c", "d", "e", "f", "g" };
  174.   for (int i = 0; i < sizeof(e) / sizeof(e[0]); i++) {
  175.     search_g(root);
  176.     root = delete_and_print(root, e[i]);
  177.   }
  178.   return EXIT_SUCCESS;
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement