Drzewa Avl Algorytm Rotacji RR

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 19

1

DRZEWA AVL
Algorytm rotacji RR
AVLNode * AVLrotationRR(AVLNode * &root, AVLNode * A)
{
AVLNode * B = A->right, * P = A->p;

A->right = B->left;
if(A->right) A->right->p = A;
B->left = A;
B->p = P;
A->p = B;
if(P)
{
if(P->left == A) P->left = B; else P->right = B;
}
else root = B;

if(B->bf == -1)
{
A->bf = B->bf = 0;
}
else
{
A->bf = -1; B->bf = 1;
}
return B;
}

Algorytm rotacji LL
AVLNode * AVLrotationLL(AVLNode * &root, AVLNode * A)
{
AVLNode * B = A->left, * P = A->p;

A->left = B->right;
if(A->left) A->left->p = A;
B->right = A;
B->p = P;
A->p = B;
if(P)
{
if(P->left == A) P->left = B; else P->right = B;
}
else root = B;

if(B->bf == 1)
{
A->bf = B->bf = 0;
}
else
{
A->bf = 1; B->bf = -1;
}

return B;
}
2
Algorytm rotacji RL
AVLNode * AVLrotationRL(AVLNode * &root, AVLNode * A)
{
AVLNode * B = A->right, * C = B->left, * P = A->p;

B->left = C->right;
if(B->left) B->left->p = B;
A->right = C->left;
if(A->right) A->right->p = A;
C->left = A;
C->right = B;
A->p = B->p = C;
C->p = P;
if(P)
{
if(P->left == A) P->left = C; else P->right = C;
}
else root = C;

A->bf = (C->bf == -1) ? 1 : 0;
B->bf = (C->bf == 1) ? -1 : 0;
C->bf = 0;

return C;
}
Algorytm rotacji LR
AVLNode * AVLrotationLR(AVLNode * &root, AVLNode * A)
{
AVLNode * B = A->left, * C = B->right, * P = A->p;

B->right = C->left;
if(B->right) B->right->p = B;
A->left = C->right;
if(A->left) A->left->p = A;
C->right = A;
C->left = B;
A->p = B->p = C;
C->p = P;
if(P)
{
if(P->left == A) P->left = C; else P->right = C;
}
else root = C;

A->bf = (C->bf == 1) ? -1 : 0;
B->bf = (C->bf == -1) ? 1 : 0;
C->bf = 0;

return C;
}

3
Wstawianie wza w drzewie AVL
bool AVLinsert(AVLNode * &root, AVLNode * n)
{
AVLNode * x = root, * y, * z;

y = n->left = n->right = NULL;
n->bf = 0;

while(x)
{
if(x->key == n->key)
{
delete n;
return false;
}
y = x;
x = (n->key < x->key) ? x->left : x->right;
}

if(!(n->p = y))
{
root = n;
return true;
}

if(n->key < y->key) y->left = n; else y->right = n;
if(y->bf)
{
y->bf = 0;
return true;
}
y->bf = (y->left == n) ? 1 : -1;
z = y->p;
while(z)
{
if(z->bf) break;
z->bf = (z->left == y) ? 1 : -1;
y = z; z = z->p;
}

if(!z) return true;

if(z->bf == 1)
{
if(z->right == y)
{
z->bf = 0;
return true;
}
if(y->bf == -1) AVRrotationLR(root,z); else AVRrotationLL(root,z);
return true;
}
else
{
if(z->left == y)
{
z->bf = 0;
return true;
}
if(y->bf == 1) AVRrotationRL(root,z); else AVRrotationRR(root,z);
4
return true;
}
}

Usuwanie wza z drzewa AVL
AVLNode * AVLremove(AVLNode * &root, AVLNode * x)
{
AVLNode * t, * y, * z;
bool nest;

if((x->left) && (x->right))
{
y = remove(pred(x));
nest = false;
}
else
{
if(x->left)
{
y = x->left; x->left = NULL;
}
else
{
y = x->right; x->right = NULL;
}
x->bf = 0;
nest = true;
}

if(y)
{
y->p = x->p;
if(y->left = x->left) y->left->p = y;
if(y->right = x->right) y->right->p = y;
y->bf = x->bf;
}

if(x->p)
{
if(x->p->left == x) x->p->left = y; else x->p->right = y;
}
else root = y;

if(nest)
{
z = y;
y = x->p;
while(y)
{
if(!(y->bf))
{

5
// Przypadek nr 1

y->bf = (y->left == z) ? -1 : 1;
break;
}
else
{
if(((y->bf == 1) && (y->left == z)) || ((y->bf == -1) && (y-
>right == z)))
{

// Przypadek nr 2

y->bf = 0;
z = y; y = y->p;
}
else
{
t = (y->left == z) ? y->right : y->left;
if(!(t->bf))
{

// Przypadek 3A

if(y->bf == 1) AVLrotationLL(root, y); else AVLrotationRR(root,
y);
break;
}
else if(y->bf == t->bf)
{

// Przypadek 3B

if(y->bf == 1) AVLrotationLL(root, y); else AVLrotationRR(root,
y);
z = t; y = t->p;
}
else
{

// Przypadek 3C

if(y->bf == 1) AVLrotationLR(root, y); else AVLrotationRL(root,
y);
z = y->p; y = z->p;
}
}
}
}
}
return x;
}
6
Program testowy
Program umoliwia przetestowanie poszczeglnych operacji na drzewie BST.
// Test procedur obsugi drzewa BST
// (C)2008 mgr Jerzy Waaszek
// Koo informatyczne I LO w Tarnowie
//-----------------------------------

#include <iostream>

using namespace std;

// definicja typu danych reprezentujcego wze drzewa BST
//--------------------------------------------------------

struct BSTNode
{
BSTNode * p, * left, * right;
int key;
// tutaj mona umieszcza inne pola danych
};

// Definicja klasy obsugujcej drzewo BST
//----------------------------------------

class BST
{
public:
BSTNode * root; // korze drzewa
int count; // liczba wzw

BST();
~BST();
bool insert(BSTNode * n);
BSTNode * search(int key);
int maxKey(BSTNode * x);
int minKey(BSTNode * x);
BSTNode * maxNode(BSTNode * x);
BSTNode * minNode(BSTNode * x);
BSTNode * pred(BSTNode * x);
BSTNode * succ(BSTNode * x);
BSTNode * remove(BSTNode * x);
void preorder(BSTNode * x);
void inorder(BSTNode * x);
void postorder(BSTNode * x);
void walk(BSTNode * x);
void coutBSTcount();
};

// **********************************************
// *** Definicje funkcji skadowych klasy BST ***
// **********************************************

// Konstruktor klasy BST
//----------------------

7
BST::BST()
{
root = NULL;
count = 0;
}

// Destruktor klasy BST
//---------------------

BST::~BST()
{
while(root) delete(remove(root));
}

// Wstawia element do struktury BST
//---------------------------------

bool BST::insert(BSTNode * n)
{
BSTNode * y, * x = root;

y = n->left = n->right = NULL;

while(x)
{
if(n->key == x->key)
{
delete n;
return false;
}
y = x;
x = (n->key < x->key) ? x->left : x->right;
}

n->p = y;

if(!y) root = n;
else if(n->key < y->key) y->left = n;
else y->right = n;

count++;
return true;
}

// Wyszukuje element wg wartoci klucza
//-------------------------------------

BSTNode * BST::search(int key)
{
BSTNode * x = root;

while((x) && (x->key != key))
x = (key < x->key) ? x->left : x->right;

return x;
}

// Zwraca masymaln warto klucza
//--------------------------------

8
int BST::minKey(BSTNode * x)
{
while(x->left) x = x->left;
return x->key;
}

// Zwraca minimaln warto klucza
//--------------------------------

int BST::maxKey(BSTNode * x)
{
while(x->right) x = x->right;
return x->key;
}

// Zwraca wze z maksymalnym kluczem
//-----------------------------------

BSTNode * BST::minNode(BSTNode * x)
{
while(x->left) x = x->left;
return x;
}

// Zwraca wze z minimalnym kluczem
//----------------------------------

BSTNode * BST::maxNode(BSTNode * x)
{
while(x->right) x = x->right;
return x;
}

// Zwraca wze poprzednika
//-------------------------

BSTNode * BST::pred(BSTNode * x)
{
if(x->left) return maxNode(x->left);

BSTNode * y;

do
{
y = x;
x = x->p;
} while(x && (x->right != y));

return x;
}

// Zwraca wze nastpnika
//------------------------

BSTNode * BST::succ(BSTNode * x)
{
if(x->right) return minNode(x->right);

BSTNode * y;


9
do
{
y = x;
x = x->p;
} while(x && (x->left != y));

return x;
}

// Usuwa element x ze struktury BST. Zwraca usunity wze
//--------------------------------------------------------

BSTNode * BST::remove(BSTNode * x)
{
BSTNode * y = x->p, * z;

if((x->left) && (x->right))
{
z = (rand() % 2) ? remove(pred(x)) : remove(succ(x));
z->left = x->left; if(z->left) z->left->p = z;
z->right = x->right; if(z->right) z->right->p = z;
count++;
}
else z = (x->left) ? x->left : x->right;

if(z) z->p = y;

if(!y) root = z;
else if(y->left == x) y->left = z; else y->right = z;

count--;
return x;
}


// Przechodzi przez BST metod preorder
//-------------------------------------

void BST::preorder(BSTNode * x)
{
if(x)
{
cout << x->key << endl; // tutaj przetwarzamy biecy wze
preorder(x->left);
preorder(x->right);
}
}

// Przechodzi przez BST metod inorder
//------------------------------------

void BST::inorder(BSTNode * x)
{
if(x)
{
inorder(x->left);
cout << x->key << endl; // tutaj przetwarzamy biecy wze
inorder(x->right);
}
}

10
// Przechodzi przez BST metod postorder
//--------------------------------------

void BST::postorder(BSTNode * x)
{
if(x)
{
postorder(x->left);
postorder(x->right);
cout << x->key << endl; // tutaj przetwarzamy biecy wze
}
}

// Przechodzi przez drzewo wypisujc zawarto wzw
//---------------------------------------------------

void BST::walk(BSTNode * x)
{
cout << x->key << " : Left-> ";
if(x->left) cout << x->left->key;
else cout << "NIL";
cout << ", Right-> ";
if(x->right) cout << x->right->key;
else cout << "NIL";
cout << endl;
if(x->left) walk(x->left);
if(x->right) walk(x->right);
}


// Wypisuje do cout liczb wzw drzewa BST
//------------------------------------------

void BST::coutBSTcount()
{
cout << "\nLiczba wezlow drzewa BST : " << count << endl << endl;
}

// **********************************
// *** Funkcje obsugi opcji menu ***
// **********************************


// Dodaje nowe wzy do drzewa BST
//--------------------------------

void add(BST * T)
{
cout << "Dodawanie nowych wezlow do drzewa BST\n"
"-------------------------------------\n\n";
T->coutBSTcount();
cout << "Podaj liczbe wezlow do utworzenia, a nastepnie wprowadz
odpowiednia\n"
"liczbe kluczy nowych wezlow.\n\n";

int i,n;

BSTNode * x;

cin >> n;
for(i = 0; i < n; i++)
11
{
x = new BSTNode;
cin >> x->key;
T->insert(x);
}

cout << endl;
T->walk(T->root);
T->coutBSTcount();
}

// Usuwa wze o zadanym kluczu
//-----------------------------

void del(BST * T)
{
cout << "Usuwanie wezla drzewa BST o zadanym kluczu\n"
"------------------------------------------\n\n";
T->coutBSTcount();

BSTNode * x;
int key;

cout << "Podaj klucz usuwanego wezla : "; cin >> key;

x = T->search(key);

if(x)
{
delete T->remove(x);
cout << endl;
if(T->root) T->walk(T->root);
T->coutBSTcount();
}
else cout << "\nBrak wezla o takim kluczu\n";
}

// Sprawdza, czy drzewo zawiera wze o zadanym kluczu
//----------------------------------------------------

void check(BST * T)
{
cout << "Sprawdzenie obecnosci wezla o danym kluczu w drzewie BST\n"
"--------------------------------------------------------\n\n"
"Podaj klucz wezla : ";

int key;

cin >> key;

cout << endl;

if(T->search(key)) cout << "Wezel znaleziony.\n";
else cout << "W drzewie BST brak wezla o podanym kluczu\n";
}

// Znajduje minimalny i maksymalny klucz
//--------------------------------------

12
void minmax(BST * T)
{
cout << "Znajdowanie minimalnego i maksymalnego klucza w drzewie BST\n"
"-----------------------------------------------------------\n\n"
"Klucz minimalny : " << T->minKey(T->root) << endl <<
"Klucz maksymalny : " << T->maxKey(T->root) << endl;
}

// Znajduje poprzednik wza o zadanym kluczu
//-------------------------------------------

void pred(BST * T)
{
cout << "Znajdowanie poprzednika w drzewie BST\n"
"-------------------------------------\n\n"
"Podaj klucz wezla : ";
int key;
BSTNode * x;

cin >> key;
cout << endl;

x = T->search(key);

if(x)
{
x = T->pred(x);
if(x) cout << "Poprzednikiem [" << key << "] jest " << x->key << endl;
else cout << "Wezel [" << key << "] nie posiada poprzednika\n";
}
else cout << "Wezel o podanym kluczu nie istnieje w drzewie BST\n";
}

// Znajduje nastpnik wza o zadanym kluczu
//------------------------------------------

void succ(BST * T)
{
cout << "Znajdowanie nastepnika w drzewie BST\n"
"------------------------------------\n\n"
"Podaj klucz wezla : ";
int key;
BSTNode * x;

cin >> key;
cout << endl;

x = T->search(key);

if(x)
{
x = T->succ(x);
if(x) cout << "Nastepnikiem [" << key << "] jest " << x->key << endl;
else cout << "Wezel [" << key << "] nie posiada nastepnika\n";
}
else cout << "Wezel o podanym kluczu nie istnieje w drzewie BST\n";
}

13
// Przechodzi przez drzewo algorytmem preorder
//--------------------------------------------

void preorder(BST * T)
{
cout << "Przechodzenie drzewa BST algorytmem preorder\n"
"--------------------------------------------\n\n";
T->preorder(T->root);
}

// Przechodzi przez drzewo algorytmem inorder
//--------------------------------------------

void inorder(BST * T)
{
cout << "Przechodzenie drzewa BST algorytmem inorder\n"
"-------------------------------------------\n\n";
T->inorder(T->root);
}

// Przechodzi przez drzewo algorytmem postorder
//--------------------------------------------

void postorder(BST * T)
{
cout << "Przechodzenie drzewa BST algorytmem postorder\n"
"---------------------------------------------\n\n";
T->postorder(T->root);
}

// **********************
// *** Program gwny ***
// **********************

main()
{
BST * T = new BST();
int choice;

do
{
system("cls"); // w Linuxie wstaw clear
cout << "Test funkcji obslugi drzew poszukiwan binarnych\n"
"===============================================\n\n"
"Wybor Funkcja\n"
"-------------\n"
" [0] Koniec\n"
" [1] Dodaj wezly\n"
" [2] Usun wezel\n"
" [3] Sprawdz obecnosc wezla\n"
" [4] Wezel min i max\n"
" [5] Poprzednik\n"
" [6] Nastepnik\n"
" [7] Preorder\n"
" [8] Inorder\n"
" [9] Postorder\n"
"--------------\n"
"Twoj wybor : ";
cin >> choice;
system("cls");
switch(choice)
14
{
case 1 : add(T); break;
case 2 : del(T); break;
case 3 : check(T); break;
case 4 : minmax(T); break;
case 5 : pred(T); break;
case 6 : succ(T); break;
case 7 : preorder(T); break;
case 8 : inorder(T); break;
case 9 : postorder(T); break;
}
if((choice >= 1) && (choice <= 9))
{
cout << endl;
system("pause");
}
} while(choice);

delete T;
}
15
#include<iostream>
using namespace std;

struct node{
int val;
node *left;
node *right;
node *p;
};

//Wstawianie elementu do drzewa
void push(node *&head, int value){
if(head == NULL){
head = new node;
head->left = NULL;
head->right = NULL;
head->val = value;
//return head;
}
else{
if(value<head->val) {
push(head->left, value);
//return head;
}
else{
push(head->right, value);
//return head;
}
}
};
//Inicjalizzacja drzew
void InitTree(node *&head){
int nodes;
int i, x;
cout << "Podaj liczbe wezlow:" << endl;
cin >> nodes;

for(i=0; i<nodes; i++){
cout << "Podaj wartosc: ";
cin >> x;
push(head, x);
cout << "Wartosc dolozona." << endl;
}
}
//***************WYPISYWANIE DRZEW*********************
//Wyswietlanie drzewa - Inorder (ronaco)
void DisplayInorder(node *head){
if(head != NULL){
DisplayInorder(head->left);
cout << head->val << " ";
DisplayInorder(head->right);
}
};
//Wyswietlanie drzewa - Preorder
void DisplayPreorder(node *head){
if(head != NULL){
cout << head->val << " ";
DisplayPreorder(head->left);
DisplayPreorder(head->right);
}
};
16
//Wyswietlanie drzewa - Postorder
void DisplayPostorder(node *head){
if(head != NULL){
DisplayPostorder(head->left);
DisplayPostorder(head->right);
cout << head->val << " ";
}
};
//Wyswietlanie drzewa w kolejnosci odwrotnej do postorder
void DisplayReversePostorder(node *head){
if(head != NULL){
cout << head->val << " ";
DisplayReversePostorder(head->right);
DisplayReversePostorder(head->left);
}
};
//***************************************************
//Usuwanie drzewa
node* DeleteTree(node *&head){
node *p;
if(head!=NULL){
DeleteTree(head->left);
DeleteTree(head->right);
p=head;
head=NULL;
delete p;
}
}
//******************WYSZUKIWANIE W DRZEWACH*************************
// Funkcja zwraca wskanik do wza zawierajcego wartosc, jeli taki
wze znajduje si
// w drzewie, w przeciwnym razie zwraca warto NULL
node* FindNode (node *&head, int val) {
if(head!=NULL && val == head->val) return head;

if(val < head->val)
return FindNode(head->left, val);
else
return FindNode(head->right, val);
}
//Wyszukianie rekurenyjne
node* SearchRek(node *&head, int val) {
if((head!=NULL) || (val == head->val)) return head;

if(val < head->val)
return SearchRek(head->left, val);
else
return SearchRek(head->right, val);
}
//Wyszukianie iteracyjne (efektywniejsze)
node* SearchIter(node *&head, int val) {
while((head!=NULL) && (val != head->val)){
if(val < head->val) head = head->left;
else head = head->right;
}
return head;
}
//Znajdowanie minimum
node* FindMin(node *&head){
node *pom = head;
while(pom->left !=NULL)
17
pom = pom->left;
return pom;
}
//Znajdowanie maksimum
node* FindMax(node *&head){
node *pom = head;
while(pom->right !=NULL)
pom = pom->right;
return pom;
}

//Zwrca wezel poprzednika
node* Predecessor(node *&head){
if(head->left) return FindMax(head->left);

node * y;

do
{
y = head;
head = head->p;
} while(head && (head->right != y));

return head;
}


//Obliczanie ilosci wezlow w drzewie
int NodesNumber(node *&head){
if(head==NULL) return 0;
else return NodesNumber(head->left) + NodesNumber(head->right) + 1;
}
//Obliczenie wysokosci drzewa
int TreeHeight(node *head){
if(head==NULL) return 0;
else return 1 + TreeHeight(head->right) + TreeHeight(head->left);
}
//Funkcja znajdujaca liczbe lisci
int LeavesNumber (node *head){
if(head==NULL) return 0;
if(head->left == head->right) return 1; //Dwa NULLE
else return LeavesNumber((head->left) + LeavesNumber(head->right));
}
//Funkcja zwracajaca ilosc wezlow na n-tym poziomie drzewa
int LevelNodes (node * head, int n){
if(head==NULL) return 0;
if(n==0) return 1;
return LevelNodes(head->left, n-1) + LevelNodes(head->right, n-1);
}

int main()
{
int N;
node *head=NULL;
cout << "----------------------------------------" << endl;
cout << "---------------DRZEWO BST---------------" << endl;
cout << "----------------------------------------" << endl << endl;

cout << "Wcisnij:" << endl;
cout << "1 - aby zainicjowac drzewo," << endl;
cout << "2 - aby wyswietlic drzewo inorder," << endl;
18
cout << "3 - aby wyswietlic drzewo preorder," << endl;
cout << "4 - aby wyswietlic drzewo postorder," << endl;
cout << "5 - aby wyswietlic drzewo w kolejnosci odwrotnej do
postorder," << endl;
cout << "6 - aby wstawic element do drzewa," << endl;
cout << "7 - aby znalezdz adres danej wartosci," << endl;
cout << "8 - aby znalezdz minimum," << endl;
cout << "9 - aby znalezdz maksimum," << endl;
cout << "10 - aby usunac drzewo," << endl;
cout << "11 - aby obliczyc ilosc wezlow w drzewie," << endl;
cout << "12 - aby obliczyc ilosc wysokosc drzewa," << endl;
cout << "13 - aby obliczyc liczbe lisci w drzewie." << endl;
cout << "14 - aby obliczyc liczbe wezlow na n-tym poziomie drzewa," <<
endl;
//cout << "11 - aby wyznaczyc trase miedzy podanymi elementami," <<
endl;
cout << "0 - aby zakonczyc." << endl << endl << endl;

do{
cout << endl << "Wybierz numer operacji: ";
cin >>N;
switch(N){
case 1:
InitTree(head);
break;

case 2:
DisplayInorder(head);
break;

case 3:
DisplayPreorder(head);
break;

case 4:
DisplayPostorder(head);
break;

case 5:
DisplayReversePostorder(head);
break;

case 6:
int temp;
cout << "Podaj wartosc: " << endl;
cin >> temp;
push(head, temp);
break;

case 7:
cout << "Podaj wartosc, ktorej adres chcesz wyszukac: ";
cin >> temp;
cout << endl << "Adres szukanej wartosci to: " <<
FindNode(head, temp) << endl;
break;

case 8:
cout << "Minimalna wartosc to: " << FindMin(head)->val <<
endl;
break;

19
case 9:
cout << "Maksymalna wartosc to: " << FindMax(head)->val <<
endl;
break;

case 10:
DeleteTree(head);
cout << "Drzewo usuniete." << endl;
break;

case 11:
cout << "Liczba wezlow w drzewie wynosi: " <<
NodesNumber(head) <<"." << endl;
break;

case 12:
cout << "Wysokosc drzewa wynosi: " << TreeHeight(head) <<
endl;
break;

case 13:
cout << "Ilosc lisci w drzewie wynosi: " <<
LeavesNumber(head) << endl;
break;

case 14:
int n;
cout << "Podaj poziom drzewa: ";
cin >> n;
cout << "Liczba wezlow na " << n << " pozomie drzewa
wynosi: " << LevelNodes(head, n) << endl;
break;



}
} while (N!=0);


/*cout << "Drzewo:" << endl;
DisplayInorder(head);

cout << endl << "Podaj szukana wartosc: ";
cin >> x;
cout << "Adres wartosci to: " << FindNode(head, x) << endl;
*/


return;

}

You might also like