Advertisement
soulrpg

AISD_Drzewa_v3

Apr 7th, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.34 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <vector>
  5. #include <fstream>
  6. #include <typeinfo>
  7. #include <math.h>
  8.  
  9. using namespace std;
  10.  
  11. // struktura pojedynczego wezla
  12. struct Element
  13. {
  14.     int klucz;
  15.     Element *wsk_prawy;
  16.     Element *wsk_lewy;
  17.     Element *wsk_gora;
  18.     // konstruktor automatycznie ustawia odpowiednie wartosci
  19.     Element(int wartosc)
  20.     {
  21.         klucz = wartosc;
  22.         wsk_prawy = NULL;
  23.         wsk_lewy = NULL;
  24.         wsk_gora = NULL;
  25.     }
  26. };
  27.  
  28. // generuje malejacy ciag o odpowiedniej dlugosci
  29. void generate_sequence(int sequence_size, vector <int> &numbers)
  30. {
  31.     srand(time(NULL));
  32.     numbers.push_back(rand()%100+1);
  33.     for(int i = 1; i < sequence_size; i++)
  34.     {
  35.         numbers.insert(numbers.begin(), numbers[0]+rand()%100+1);
  36.     }
  37. }
  38.  
  39. // przeksztalca ciag poprzez polowienie binarne na ciag, ktory pozwoli zbudowac drzewo AVL
  40. //                    FROM                  TO
  41. void sequence_for_AVL(vector <int> numbers, vector <int> &numbers_altered, int lewy, int prawy)
  42. {
  43.     int srodek = (lewy+prawy)/2;
  44.     //cout << "Numbers[srodek] " << "[" << srodek << "] " << numbers[srodek] << endl;
  45.     numbers_altered.push_back(numbers[srodek]);
  46.     // wywoluje polowienie rekurencyjnie
  47.     if(srodek-lewy>0)
  48.     {
  49.         sequence_for_AVL(numbers, numbers_altered, lewy, srodek);
  50.     }
  51.     if(prawy-srodek>1)
  52.     {
  53.         sequence_for_AVL(numbers, numbers_altered, srodek+1, prawy);
  54.     }
  55. }
  56.  
  57. // dodaje element (wartosc) do drzewa
  58. void add_element(Element* &wezel, int wartosc)
  59. {
  60.     // jezeli wezel jest pusty to po prostu wstawia na niego nowy element
  61.     if(wezel == NULL)
  62.     {
  63.         wezel = new Element(wartosc);
  64.     }
  65.     // jezeli nie no to wywolujemy funkcje rekurencyjnie dla lewego syna lub prawego
  66.     else
  67.     {
  68.         if(wartosc > wezel->klucz)
  69.         {
  70.             if(wezel->wsk_prawy == NULL)
  71.             {
  72.                 wezel->wsk_prawy = new Element(wartosc);
  73.                 wezel->wsk_prawy->wsk_gora = wezel;
  74.             }
  75.             else
  76.             {
  77.                 add_element(wezel->wsk_prawy, wartosc);
  78.             }
  79.  
  80.         }
  81.         if(wartosc < wezel->klucz)
  82.         {
  83.             if(wezel->wsk_lewy == NULL)
  84.             {
  85.                 wezel->wsk_lewy = new Element(wartosc);
  86.                 wezel->wsk_lewy->wsk_gora = wezel;
  87.             }
  88.             else
  89.             {
  90.                 add_element(wezel->wsk_lewy, wartosc);
  91.             }
  92.         }
  93.     }
  94. }
  95.  
  96. void wyszukaj_MAX(Element* wezel)
  97. {
  98.     if(wezel->wsk_prawy == NULL)
  99.     {
  100.         cout << endl;
  101.         cout << "MAX: " << wezel->klucz << endl;
  102.         cout << "---KONIEC PROCEDURY---" << endl;
  103.     }
  104.     else
  105.     {
  106.         cout << wezel->klucz << " ";
  107.         wyszukaj_MAX(wezel->wsk_prawy);
  108.     }
  109. }
  110.  
  111. void wyszukaj_MIN(Element* wezel)
  112. {
  113.     if(wezel->wsk_lewy == NULL)
  114.     {
  115.         cout << endl;
  116.         cout << "MIN: " << wezel->klucz << endl;
  117.         cout << "---KONIEC PROCEDURY---" << endl;
  118.     }
  119.     else
  120.     {
  121.         cout << wezel->klucz << " ";
  122.         wyszukaj_MIN(wezel->wsk_lewy);
  123.     }
  124. }
  125.  
  126. Element* wyszukaj_nastepnik(Element* wezel)
  127. {
  128.     while(wezel->wsk_lewy!=NULL)
  129.     {
  130.         wezel = wezel->wsk_lewy;
  131.     }
  132.     return wezel;
  133. }
  134.  
  135. Element* wyszukaj_element(int klucz, Element* wezel)
  136. {
  137.     //cout << "Wywolanie funkcji: " << wezel->klucz << " Adres: " << wezel  << endl;
  138.     if(wezel == NULL)
  139.     {
  140.         return NULL;
  141.     }
  142.  
  143.     if(wezel->klucz == klucz)
  144.     {
  145.         return wezel;
  146.     }
  147.     else if(klucz > wezel->klucz)
  148.     {
  149.         wyszukaj_element(klucz, wezel->wsk_prawy);
  150.     }
  151.     else
  152.     {
  153.         wyszukaj_element(klucz, wezel->wsk_lewy);
  154.     }
  155. }
  156.  
  157. void usuwanie_elementu(int klucz, Element* &wezel)
  158. {
  159.      if(wezel == NULL)
  160.         return;
  161.     if(wezel->klucz == klucz)
  162.     {
  163.         //cout << "Znaleziono klucz!" << endl;
  164.         if(wezel->wsk_prawy == NULL && wezel->wsk_lewy == NULL)
  165.         {
  166.             //cout << "brak dzieci" << endl;
  167.             if(wezel->wsk_gora->klucz > wezel->klucz)
  168.             {
  169.                 wezel->wsk_gora->wsk_lewy = NULL;
  170.             }
  171.             else
  172.             {
  173.                 wezel->wsk_gora->wsk_prawy = NULL;
  174.             }
  175.             delete wezel;
  176.         }
  177.         else if(wezel->wsk_prawy == NULL)
  178.         {
  179.             Element *tmp_adress = wezel->wsk_lewy;
  180.             wezel->klucz = wezel->wsk_lewy->klucz;
  181.             wezel->wsk_prawy = tmp_adress->wsk_prawy;
  182.             wezel->wsk_lewy = wezel->wsk_lewy->wsk_lewy;
  183.             delete tmp_adress;
  184.         }
  185.         else if(wezel->wsk_lewy == NULL)
  186.         {
  187.             Element *tmp_adress = wezel->wsk_prawy;
  188.             wezel->klucz = wezel->wsk_prawy->klucz;
  189.             wezel->wsk_prawy = wezel->wsk_prawy->wsk_prawy;
  190.             wezel->wsk_lewy = tmp_adress->wsk_lewy;
  191.             delete tmp_adress;
  192.         }
  193.         else
  194.         {
  195.             Element *nastepnik = wyszukaj_nastepnik(wezel->wsk_prawy);
  196.             Element *syn_nastepnika = nastepnik->wsk_prawy;
  197.             wezel->klucz = nastepnik->klucz;
  198.             nastepnik->klucz = syn_nastepnika->klucz;
  199.             nastepnik->wsk_prawy = syn_nastepnika->wsk_prawy;
  200.             nastepnik->wsk_lewy = syn_nastepnika->wsk_lewy;
  201.             delete syn_nastepnika;
  202.         }
  203.     }
  204.     else if(klucz > wezel->klucz)
  205.     {
  206.         usuwanie_elementu(klucz, wezel->wsk_prawy);
  207.     }
  208.     else
  209.     {
  210.         usuwanie_elementu(klucz, wezel->wsk_lewy);
  211.     }
  212. }
  213.  
  214. // wyswietla cale drzewo w porzadku pre-order
  215. void wyswietl_preorder(Element* wezel)
  216. {
  217.     if(wezel == NULL)
  218.         return;
  219.     cout << wezel->klucz << " ";
  220.     // wersja robocza
  221.     //cout << wezel->klucz << " Lewy: " << wezel->wsk_lewy << " Prawy: " << wezel->wsk_prawy << " Góra: " << wezel->wsk_gora << endl;
  222.     wyswietl_preorder(wezel->wsk_lewy);
  223.     wyswietl_preorder(wezel->wsk_prawy);
  224. }
  225.  
  226. // wyswietla cale drzewo w porzadku in-order
  227. void wyswietl_inorder(Element* wezel)
  228. {
  229.     if(wezel == NULL)
  230.         return;
  231.     wyswietl_inorder(wezel->wsk_lewy);
  232.     cout << wezel->klucz << " ";
  233.     wyswietl_inorder(wezel->wsk_prawy);
  234. }
  235.  
  236.  
  237. // usuwa cale drzewo w porzadku post-order
  238. void usun_postorder(Element* &wezel)
  239. {
  240.     if(wezel == NULL)
  241.         return;
  242.     usun_postorder(wezel->wsk_lewy);
  243.     usun_postorder(wezel->wsk_prawy);
  244.     delete wezel;
  245. }
  246.  
  247. // dotyczy rotacji
  248. void zmiana_na_liste(Element* &pseudo_root)
  249. {
  250.     Element* ogon = pseudo_root;
  251.     Element* pozostalosc = pseudo_root->wsk_prawy;
  252.     while(pozostalosc!=NULL)
  253.     {
  254.         if(pozostalosc->wsk_lewy==NULL)
  255.         {
  256.             ogon = pozostalosc;
  257.             pozostalosc = pozostalosc->wsk_prawy;
  258.         }
  259.         else
  260.         {
  261.             Element* temp = pozostalosc->wsk_lewy;
  262.             pozostalosc->wsk_lewy = temp->wsk_prawy;
  263.             temp->wsk_prawy = pozostalosc;
  264.             pozostalosc = temp;
  265.             ogon->wsk_prawy = temp;
  266.         }
  267.     }
  268. }
  269.  
  270. //dotyczy rotacji
  271. void kompresuj(Element* &pseudo_root, int licznik)
  272. {
  273.     Element* skaner = pseudo_root;
  274.     for(int i = 0; i<licznik; i++)
  275.     {
  276.         Element* dziecko = skaner->wsk_prawy;
  277.         skaner->wsk_prawy = dziecko->wsk_prawy;
  278.         skaner = skaner->wsk_prawy;
  279.         dziecko->wsk_prawy = skaner->wsk_lewy;
  280.         skaner->wsk_lewy = dziecko;
  281.     }
  282. }
  283.  
  284. //dotyczy rotacji
  285. void lista_na_drzewo(Element* &pseudo_root, int wielkosc)
  286. {
  287.     int ilosc_lisci = wielkosc + 1 - pow(2, log2(wielkosc+1));
  288.     kompresuj(pseudo_root, ilosc_lisci);
  289.     wielkosc = wielkosc - ilosc_lisci;
  290.     while(wielkosc > 1)
  291.     {
  292.         kompresuj(pseudo_root, wielkosc/2);
  293.         wielkosc = wielkosc/2;
  294.     }
  295. }
  296.  
  297. // rownowarzenie drzewa
  298. Element* rotacja_DSW(Element* &wezel, int wielkosc)
  299. {
  300.     // tworzy kopie korzenia drzewa
  301.     Element* pseudo_root = new Element(NULL);
  302.     pseudo_root->wsk_prawy = wezel;
  303.     zmiana_na_liste(pseudo_root);
  304.     lista_na_drzewo(pseudo_root, wielkosc);
  305.     wezel = pseudo_root->wsk_prawy;
  306.     delete pseudo_root;
  307. }
  308.  
  309. int main()
  310. {
  311.     int sequence_size;
  312.     bool proper_value;
  313.     bool quit = false;
  314.     bool good_input = false;
  315.     int choice;
  316.     int klucz_poddrzewa;
  317.     int ile_usunac;
  318.     int klucz_usuwania;
  319.     bool user_input;
  320.     vector <int> numbers;
  321.     vector <int> numbers_altered;
  322.     Element *root_BST = NULL;
  323.     Element *root_AVL = NULL;
  324.     Element *szukany = NULL;
  325.     while(!quit)
  326.     {
  327.         proper_value = false;
  328.         while(!proper_value)
  329.         {
  330.             cout << "Podaj wielkosc ciagu malejacego: ";
  331.             cin >> sequence_size;
  332.             if(cin && sequence_size > 0)
  333.             {
  334.                 generate_sequence(sequence_size, numbers);
  335.                 sequence_for_AVL(numbers, numbers_altered, 0, numbers.size());
  336.                 // tworzenie drzew BST i AVL
  337.                 for(int i = 0; i<numbers.size(); i++)
  338.                 {
  339.                     add_element(root_BST, numbers[i]);
  340.                     add_element(root_AVL, numbers_altered[i]);
  341.                 }
  342.                 // wyjscie z petli wewnetrznej programu
  343.                 proper_value = true;
  344.             }
  345.         }
  346.         while(!good_input)
  347.         {
  348.             // do zrobienia:  7 jeszcze jest wyszukaj MIN XD, trzeba by tu pozmienaic numerki
  349.             cout << "Wybierz akcje: 1)Wyszukaj MAX, 2)Usun wybrane wezly, 3)Wypisz pre-order" << endl;
  350.             cout << "4)Wypisz in-order, 5)Usun drzewo post-order, 6)Wypisz poddrzewo (pre-order)," << endl;
  351.             cout << "7)Rownowarz drzewo BST(DSW), 8)Wyjscie, Wybor:";
  352.             cin >> choice;
  353.             if(!cin || choice < 0 || choice >= 9)
  354.             {
  355.                 cout << "Wybrano bledna akcje!" << endl;
  356.                 exit(0);
  357.             }
  358.             switch(choice)
  359.             {
  360.             case 1:
  361.                 cout << "Sciezka BST: ";
  362.                 wyszukaj_MAX(root_BST);
  363.                 cout << endl;
  364.                 cout << "Sciezka AVL: ";
  365.                 wyszukaj_MAX(root_AVL);
  366.                 break;
  367.             case 2:
  368.                 ile_usunac = 0;
  369.                 klucz_usuwania = 0;
  370.                 user_input = false;
  371.                 while(!user_input)
  372.                 {
  373.                     cout << "Ile wezlow usunac?:";
  374.                     cin >> ile_usunac;
  375.                     if(cin && ile_usunac > 0 && ile_usunac < numbers.size())
  376.                     {
  377.                         user_input = true;
  378.                     }
  379.                 }
  380.                 for(int i = 1; i<=ile_usunac; i++)
  381.                 {
  382.                     cout << "[" << i << "] klucz:";
  383.                     cin >> klucz_usuwania;
  384.                     if(!cin)
  385.                     {
  386.                         cout << "Zly input!" << endl;
  387.                         exit(0);
  388.                     }
  389.                     else
  390.                     {
  391.                         // usuwanie z drzewa BST
  392.                         cout << "Usuwanie wezla z drzewa BST!" << endl;
  393.                         szukany = wyszukaj_element(klucz_usuwania, root_BST);
  394.                         usuwanie_elementu(klucz_usuwania, szukany);
  395.                         // usuwanie z drzewa AVL
  396.                         cout << "Usuwanie wezla z drzewa AVL!" << endl;
  397.                         szukany = wyszukaj_element(klucz_usuwania, root_AVL);
  398.                         usuwanie_elementu(klucz_usuwania, szukany);
  399.                     }
  400.                 }
  401.                 break;
  402.             case 3:
  403.                 cout << "BST pre-order: " << endl;
  404.                 wyswietl_preorder(root_BST);
  405.                 cout << endl;
  406.                 cout << "--- KONIEC PROCEDURY ---" << endl;
  407.                 cout << "AVL pre-order: " << endl;
  408.                 wyswietl_preorder(root_AVL);
  409.                 cout << endl;
  410.                 cout << "--- KONIEC PROCEDURY ---" << endl;
  411.                 break;
  412.             case 4:
  413.                 cout << "BST in-order: " << endl;
  414.                 wyswietl_inorder(root_BST);
  415.                 cout << endl;
  416.                 cout << "--- KONIEC PROCEDURY ---" << endl;
  417.                 cout << "AVL in-order: " << endl;
  418.                 wyswietl_inorder(root_AVL);
  419.                 cout << endl;
  420.                 cout << "--- KONIEC PROCEDURY ---" << endl;
  421.                 break;
  422.             case 5:
  423.                 cout << "BST usun post-order... " << endl;
  424.                 usun_postorder(root_BST);
  425.                 cout << endl;
  426.                 cout << "--- KONIEC PROCEDURY ---" << endl;
  427.                 cout << "AVL usun post-order... " << endl;
  428.                 usun_postorder(root_AVL);
  429.                 cout << endl;
  430.                 cout << "--- KONIEC PROCEDURY ---" << endl;
  431.                 break;
  432.             case 6:
  433.                 cout << "Wypisywanie poddrzewa. Podaj klucz: ";
  434.                 cin >> klucz_poddrzewa;
  435.                 if(!cin)
  436.                 {
  437.                     cout << "Blad wejscia!" << endl;
  438.                     exit(0);
  439.                 }
  440.                 cout << "PODDRZEWO Z BST...: ";
  441.                 if(wyszukaj_element(klucz_poddrzewa, root_BST) == NULL)
  442.                 {
  443.                     cout << "Nie znaleziono wezla w strukturze o podanym kluczu!" << endl;
  444.                 }
  445.                 else
  446.                 {
  447.                     //cout << "Adres wyszukany: " << wyszukaj_element(klucz_poddrzewa, root_BST) << endl;
  448.                     wyswietl_preorder(wyszukaj_element(klucz_poddrzewa, root_BST));
  449.                     cout << endl;
  450.                 }
  451.                 cout << "PODDRZEWO Z AVL...: ";
  452.                 if(wyszukaj_element(klucz_poddrzewa, root_AVL) == NULL)
  453.                 {
  454.                     cout << "Nie znaleziono wezla w strukturze o podanym kluczu!" << endl;
  455.                 }
  456.                 else
  457.                 {
  458.                     //cout << "Adres wyszukany: " << wyszukaj_element(klucz_poddrzewa, root_AVL) << endl;
  459.                     wyswietl_preorder(wyszukaj_element(klucz_poddrzewa, root_AVL));
  460.                     cout << endl;
  461.                 }
  462.                 cout << "--- KONIEC PROCEDURY ---" << endl;
  463.                 break;
  464.             case 7:
  465.                 rotacja_DSW(root_BST, sequence_size);
  466.                 rotacja_DSW(root_AVL, sequence_size);
  467.                 break;
  468.             case 8:
  469.                 exit(0);
  470.                 break;
  471.             }
  472.         }
  473.     }
  474.     return 0;
  475. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement