Advertisement
epidzhx

AVL-tree

May 25th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.84 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. struct Pupil
  6. {
  7.     char first_name[20];
  8.     char second_name[20];
  9.     char gender[7];
  10.     char grade[4];
  11.     char birthdate[11];
  12.     char adress[100];
  13.    
  14.    
  15.     int balance;
  16.     int height;
  17.     int key;
  18.    
  19.     Pupil* Left;
  20.     Pupil* Right;
  21.     Pupil* Parent;
  22. };
  23.  
  24. struct PupilTree
  25. {
  26.     Pupil* Root;
  27. };
  28.  
  29. void InitPupil(Pupil*);
  30. bool StringStartsWith(char [], char [], int);
  31. Pupil* AddPupil(PupilTree*, Pupil*, Pupil*);
  32. int TreeHeight(Pupil*);
  33. void OverHeight(Pupil*);
  34. Pupil* RightRotation(Pupil*);
  35. Pupil* LeftRotation(Pupil*);
  36. Pupil* Balance(Pupil*);
  37. Pupil *RemovePupil(Pupil *, char first_name[]);
  38. Pupil* FindPupilBySecondName(PupilTree*, char [], Pupil*);
  39. void SavePupil(Pupil*, FILE*);
  40. void SaveTree(PupilTree*, char []);
  41. void LoadTree(PupilTree*, char []);
  42. Pupil *SearchMin(Pupil*);
  43. Pupil *DeleteMin(Pupil*);
  44. int BalanceFactor(Pupil*);
  45. void ClearTree(PupilTree*);
  46. //PupilTree* Filter(PupilTree*, Pupil*);
  47.  
  48.  
  49. int BalanceFactor(Pupil *p)
  50. {
  51.     return TreeHeight(p->Right) - TreeHeight(p->Left);
  52. }
  53.  
  54. Pupil *SearchMin(Pupil *x)
  55. {
  56.     if (x->Left) return SearchMin(x->Left);
  57.     else return x;
  58. }
  59.  
  60. Pupil *DeleteMin(Pupil *x)
  61. {
  62.     if (x->Left==0) return x->Right;
  63.     x->Left=DeleteMin(x->Left);
  64.     return Balance(x);
  65. }
  66.  
  67. void InitPupil(Pupil* pupil)
  68. {
  69.     pupil->Left = NULL;
  70.     pupil->Right = NULL;
  71.     pupil->Parent = NULL;
  72.    
  73.     pupil->height = 0;
  74. }
  75.  
  76. bool StringStartsWith(char TestArray[], char StringToFind[], int count)
  77. {
  78.     for(int i=0;i<count;i++)
  79.     {
  80.         if(TestArray[i]!=StringToFind[i])
  81.             return false;
  82.     }
  83.     return true;
  84. }
  85.  
  86. Pupil* AddPupil(PupilTree* Tree, Pupil* pupil, Pupil* Current = NULL)
  87. {
  88.     //if (Tree==NULL) return NULL;
  89.     if (Tree->Root == NULL)
  90.     {
  91.         Tree->Root = pupil;
  92.         Tree->Root->balance = 0;
  93.         return Tree->Root;
  94.     }
  95.     if (Current == NULL) Current = Tree->Root;
  96.     int c = strcmp(Current->first_name, pupil->first_name);
  97.     if (c < 0)
  98.     {
  99.         if (Current->Left != NULL)
  100.             Current->Left = AddPupil(Tree,pupil,Current->Left);
  101.         else
  102.         {
  103.             Current->Left = pupil;
  104.             pupil->height = Current->height + 1;
  105.             //Balance(pupil);
  106.         }
  107.     }
  108.     else
  109.     {
  110.         if (Current->Right != NULL)
  111.             AddPupil(Tree, pupil, Current->Right);
  112.         else
  113.         {
  114.             Current->Right = pupil;
  115.             pupil->height = Current->height + 1;
  116.             //Balance(pupil);
  117.         }
  118.     }
  119.     return Balance(Current);
  120.    
  121. }
  122.  
  123. int TreeHeight(Pupil *pupil)
  124. {
  125.     if (pupil) return pupil->height;
  126.     else return 0;
  127. }
  128.  
  129. void OverHeight(Pupil *pupil)
  130. {
  131.     int hleft = TreeHeight(pupil->Left);
  132.     int hright = TreeHeight(pupil->Right);
  133.     pupil->height = (hleft>hright ? hleft : hright)+1;
  134. }
  135.  
  136. Pupil* RightRotation(Pupil *pupil)
  137. {
  138.     Pupil *y = pupil->Left;
  139.     pupil->Left = y->Right;
  140.     y->Right = pupil;
  141.     OverHeight(pupil);
  142.     OverHeight(y);
  143.     return y;
  144. }
  145.  
  146. Pupil* LeftRotation(Pupil *pupil)
  147. {
  148.     Pupil *x = pupil->Right;
  149.     pupil->Right = x->Left;
  150.     x->Left = pupil;
  151.     OverHeight(pupil);
  152.     OverHeight(x);
  153.     return x;
  154. }
  155.  
  156. Pupil* Balance(Pupil *pupil)
  157. {
  158.     OverHeight(pupil);
  159.     if (BalanceFactor(pupil) == 2)
  160.     {
  161.         if (BalanceFactor(pupil->Right) < 0)
  162.             pupil->Right=RightRotation(pupil->Right);
  163.         return LeftRotation(pupil);
  164.     }
  165.     if (BalanceFactor(pupil) == -2)
  166.     {
  167.         if (BalanceFactor(pupil->Left) > 0)
  168.             pupil->Left = LeftRotation(pupil->Left);
  169.         return RightRotation(pupil);
  170.     }
  171.     return pupil;
  172. }
  173.  
  174. Pupil *RemovePupil(Pupil *x, char first_name[])
  175. {
  176.     if (x == NULL) return 0;
  177.     if (strcmp(x->first_name, first_name) < 0)
  178.         x->Left=RemovePupil(x->Left, first_name);
  179.     else if (strcmp(x->first_name, first_name) > 0)
  180.         x->Right=RemovePupil(x->Right, first_name);
  181.     else
  182.     {
  183.         Pupil *l = x->Left;
  184.         Pupil *r = x->Right;
  185.         free(x);
  186.         if (r == NULL) return l;
  187.         Pupil* min = SearchMin(r);
  188.         min->Right = DeleteMin(r);
  189.         min->Left=l;
  190.        
  191.         return Balance(min);
  192.     }
  193.     return Balance(x);
  194. }
  195.  
  196. Pupil* FindPupilBySecondName(PupilTree* Tree, char pupil_second_name[], Pupil* Current = NULL)
  197. {
  198.     if (Tree == NULL) return NULL;
  199.     if (Current == NULL) Current = Tree->Root;
  200.     int c = strcmp(Current->second_name, pupil_second_name);
  201.     if (c < 0)
  202.     {
  203.         if (Current->Left != NULL) return FindPupilBySecondName(Tree, pupil_second_name, Current->Left);
  204.         else return NULL;
  205.     }
  206.     if (c > 0)
  207.     {
  208.         if (Current->Right != NULL) return FindPupilBySecondName(Tree, pupil_second_name, Current->Right);
  209.         else return NULL;
  210.     }
  211.     if (c == 0)
  212.         return Current;
  213.     return NULL;
  214. }
  215.  
  216. void SavePupil(Pupil* pupil, FILE* file)
  217. {
  218.     if (file == NULL)
  219.         return;
  220.     if (pupil != NULL)
  221.     {
  222.         //fprintf(file, "%s\n%s\n%s\n%d\n%s\n%s", pupil->first_name, pupil->second_name, pupil->gender, pupil->grade, pupil->birthdate, pupil->adress);
  223.         fputs(pupil->first_name, file);
  224.         fputs("\n", file);
  225.         fputs(pupil->second_name, file);
  226.         fputs("\n", file);
  227.         fputs(pupil->gender, file);
  228.         fputs("\n", file);
  229.         fputs(pupil->grade, file);
  230.         fputs("\n", file);
  231.         fputs(pupil->birthdate, file);
  232.         fputs("\n", file);
  233.         fputs(pupil->adress, file);
  234.         fputs("\n", file);
  235.        
  236.         if (pupil->Left != NULL)
  237.             SavePupil(pupil->Left, file);
  238.         if (pupil->Right != NULL)
  239.             SavePupil(pupil->Right, file);
  240.     }
  241. }
  242.  
  243. void SaveTree(PupilTree* Tree, char file_name[])
  244. {
  245.     if (Tree == NULL) return;
  246.     FILE *file;
  247.     file = fopen(file_name, "w");
  248.     if (file == NULL)
  249.     {
  250.         printf("\nCouldn't open the file: %s", file_name);
  251.         return;
  252.     }
  253.    
  254.     SavePupil(Tree->Root, file);
  255.     fputs("NULL\n", file);
  256.     fputs("NULL", file);
  257.     fclose(file);
  258. }
  259.  
  260. void LoadTree(PupilTree* Tree, char file_name[])
  261. {
  262.     if (Tree == NULL) return;
  263.     FILE* file;
  264.     file = fopen(file_name, "r");
  265.     if (file == NULL)
  266.     {
  267.         printf("\nCouldn't open the file: %s", file_name);
  268.         return;
  269.     }
  270.     Pupil new_input_pupil;
  271.    
  272.     while (1)
  273.     {
  274.        
  275.         fgets(new_input_pupil.first_name, 20, file);
  276.         while (strcmp(new_input_pupil.first_name, "\n") == 0)
  277.         {
  278.             strcpy(new_input_pupil.first_name, "");
  279.             fgets(new_input_pupil.first_name, 20, file);
  280.         }
  281.        
  282.         fgets(new_input_pupil.second_name, 20, file);
  283.         while (strcmp(new_input_pupil.second_name, "\n") == 0)
  284.         {
  285.             strcpy(new_input_pupil.second_name, "");
  286.             fgets(new_input_pupil.second_name, 20, file);
  287.         }
  288.        
  289.         fgets(new_input_pupil.gender, 7, file);
  290.         while (strcmp(new_input_pupil.gender, "\n") == 0)
  291.         {
  292.             strcpy(new_input_pupil.gender, "");
  293.             fgets(new_input_pupil.gender, 7, file);
  294.         }
  295.        
  296.         fgets(new_input_pupil.grade, 4, file);
  297.         while (strcmp(new_input_pupil.grade, "\n") == 0)
  298.         {
  299.             strcpy(new_input_pupil.grade, "");
  300.             fgets(new_input_pupil.grade, 4, file);
  301.         }
  302.        
  303.         fgets(new_input_pupil.birthdate, 11, file);
  304.         while (strcmp(new_input_pupil.birthdate, "\n") == 0)
  305.         {
  306.             strcpy(new_input_pupil.birthdate, "");
  307.             fgets(new_input_pupil.birthdate, 11, file);
  308.         }
  309.        
  310.         fgets(new_input_pupil.adress, 100, file);
  311.         while (strcmp(new_input_pupil.adress, "\n") == 0)
  312.         {
  313.             strcpy(new_input_pupil.adress, "");
  314.             fgets(new_input_pupil.adress, 100, file);
  315.         }
  316.        
  317.         if(!StringStartsWith(new_input_pupil.first_name, "NULL", 4) && !StringStartsWith(new_input_pupil.second_name, "NULL", 4))
  318.         {
  319.             Pupil* pupil = (Pupil*)malloc(sizeof(Pupil));
  320.            
  321.             size_t len;
  322.            
  323.             len = strlen(new_input_pupil.first_name);
  324.             if (len > 0 && new_input_pupil.first_name[len-1] == '\n')
  325.                 new_input_pupil.first_name[--len] = '\0';
  326.             strcpy(pupil->first_name, new_input_pupil.first_name);
  327.            
  328.             len = strlen(new_input_pupil.second_name);
  329.             if (len > 0 && new_input_pupil.second_name[len-1] == '\n')
  330.                 new_input_pupil.second_name[--len] = '\0';
  331.             strcpy(pupil->second_name, new_input_pupil.second_name);
  332.            
  333.             len = strlen(new_input_pupil.gender);
  334.             if (len > 0 && new_input_pupil.gender[len-1] == '\n')
  335.                 new_input_pupil.gender[--len] = '\0';
  336.             strcpy(pupil->gender, new_input_pupil.gender);
  337.            
  338.             len = strlen(new_input_pupil.grade);
  339.             if (len > 0 && new_input_pupil.grade[len-1] == '\n')
  340.                 new_input_pupil.grade[--len] = '\0';
  341.             strcpy(pupil->grade, new_input_pupil.grade);
  342.            
  343.             len = strlen(new_input_pupil.birthdate);
  344.             if (len > 0 && new_input_pupil.birthdate[len-1] == '\n')
  345.                 new_input_pupil.birthdate[--len] = '\0';
  346.             strcpy(pupil->birthdate, new_input_pupil.birthdate);
  347.            
  348.             len = strlen(new_input_pupil.adress);
  349.             if (len > 0 && new_input_pupil.adress[len-1] == '\n')
  350.                 new_input_pupil.adress[--len] = '\0';
  351.             strcpy(pupil->adress, new_input_pupil.adress);
  352.            
  353.             InitPupil(pupil);
  354.             AddPupil(Tree, pupil);
  355.         }
  356.         else
  357.             break;
  358.     }
  359.     fclose(file);
  360. }
  361.  
  362. void ClearTree(PupilTree* Tree, Pupil* Current = NULL)
  363. {
  364.     if (Current == NULL) Current = Tree->Root;
  365.     if (Current == NULL) return;
  366.     if (Current->Left != NULL)
  367.         ClearTree(Tree, Current->Left);
  368.     if (Current->Right != NULL)
  369.         ClearTree(Tree, Current->Right);
  370.     free(Current);
  371. }
  372.  
  373. void InitTree(PupilTree *t)
  374. {
  375.     t->Root = NULL;
  376. }
  377.  
  378. void Filter()
  379. {
  380.     return;
  381. }
  382.  
  383. int main()
  384. {
  385.    
  386.     int is_continue = 1;
  387.     char file_name[] = "file.txt";
  388.     char name[20];
  389.     PupilTree t;
  390.     PupilTree filter_t;
  391.     InitTree(&t);
  392.     InitTree(&filter_t);
  393.     PupilTree *Tree = &t;
  394.     PupilTree *FilterTree = &filter_t;
  395.    
  396.    
  397.     while (is_continue)
  398.     {
  399.         printf("\nMenu\n\n");
  400.         printf("1 - Add pupil\n");
  401.         printf("2 - Remove pupil\n");
  402.         printf("3 - Find pupil by second name\n");
  403.         printf("4 - Save tree in file\n");
  404.         printf("5 - Load tree from file\n");
  405.         printf("6 - Filer by birthdate\n");
  406.         printf("7 - Exit\n");
  407.         printf("What to do? ");
  408.        
  409.         int action;
  410.         scanf("%d", &action);
  411.         if (action == 1)
  412.         {
  413.             Pupil *pupil = (Pupil*) malloc(sizeof(Pupil));
  414.             printf("Input data about new pupil:\nFirst name: ");
  415.             scanf("%s", pupil->first_name);
  416.             printf("Second name: ");
  417.             scanf("%s", pupil->second_name);
  418.             printf("Gender: ");
  419.             scanf("%s", pupil->gender);
  420.             printf("Grade: ");
  421.             scanf("%s", pupil->grade);
  422.             printf("Birthdate: ");
  423.             scanf("%s", pupil->birthdate);
  424.             printf("Adress: ");
  425.             scanf("%s", pupil->adress);
  426.            
  427.             InitPupil(pupil);
  428.             pupil = AddPupil(Tree, pupil);
  429.             //free(pupil);
  430.         }
  431.         else if (action == 2)
  432.         {
  433.             printf("Input first name: ");
  434.            
  435.             scanf("%s", name);
  436.             RemovePupil(Tree->Root, name);
  437.         }
  438.        
  439.         else if (action == 3)
  440.         {
  441.             printf("Input second name: ");
  442.             scanf("%s", name);
  443.             Pupil *pupil = FindPupilBySecondName(Tree, name);
  444.             if (pupil == NULL)
  445.                 printf("Not found\n");
  446.             else
  447.             {
  448.                 printf("SUCCESS!\n");
  449.                 printf("First name: %s\n", pupil->first_name);
  450.                 printf("Second name: %s\n", pupil->second_name);
  451.                 printf("Gender: %s\n", pupil->gender);
  452.                 printf("Grate: %s\n", pupil->grade);
  453.                 printf("Birthday: %s\n", pupil->birthdate);
  454.                 printf("Adress: %s\n", pupil->adress);
  455.             }
  456.         }
  457.        
  458.         else if (action == 4)
  459.             SaveTree(Tree, file_name);
  460.        
  461.         else if (action == 5)
  462.         {
  463.             //ClearTree(Tree, NULL);
  464.             LoadTree(Tree, file_name);
  465.         }
  466.         else if (action == 6)
  467.         {
  468.             Filter();
  469.         }
  470.         else if (action == 7)
  471.             is_continue = 0;
  472.         else is_continue = 1;
  473.     }
  474.     ClearTree(Tree, NULL);
  475.     return 0;
  476. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement