Advertisement
soulrpg

AISD_Drzewa_v4

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