AVL TREE insert, delete,rotation,algorithm
2012-05-15 12:06:49 来源:WEB开发网核心提示: cpp文件 #include "AVL.h"#include <iostream>#include <math.h>using namespace std;//Queue//Queue::~Queue(){QueueNode *curr = front, *next;whi
cpp文件
#include "AVL.h" #include <iostream> #include <math.h> using namespace std; //////////////////////////////Queue////////////////////////////////// Queue::~Queue() { QueueNode *curr = front, *next; while(curr) { next = curr->next; delete curr; curr = next; } } void Queue::enqueue(AVLNode *data, bool isLeading) { QueueNode *newNode = new QueueNode(data, isLeading); if(!front) //The queue is empty front = newNode; else //Insert as the new rear rear->next = newNode; rear = newNode; } QueueNode* Queue::dequeue() { if(!front) { //The queue is empty return NULL; } else { //Return the first node QueueNode *tmp = front; front = front->next; return tmp; } } ///////////////////////////////////AVL tree/////////////////////////////////// void AVLTree::destroy(AVLNode *subRoot) { if(!subRoot) return; destroy(subRoot->left); cout<<"Node "<<subRoot->key<<" deleted."<<endl; destroy(subRoot->right); delete subRoot; } int AVLTree::rGetHeight(AVLNode *subRoot) { if(!subRoot) return 0; if(subRoot->balance == -1) //subRoot's left subtree is heavier return rGetHeight(subRoot->left) + 1; else return rGetHeight(subRoot->right) + 1; } void AVLTree::printTree() { //Breadth first tree traversal if(!root) cout<<"Empty tree."<<endl; int treeHeight = this->getHeight(); Queue printQueue; printQueue.enqueue(root, true); QueueNode *curr; int space = pow(2,treeHeight+2)-1; //The spaces between tree nodes when printing the tree, nodes of a larger depth have larger space while(treeHeight >= -1) { curr = printQueue.dequeue(); //Print the space if(curr->isLeading) { treeHeight--; cout<<endl; space /= 4; for (int i=0; i<space; i++) cout<<" "; space = space*2 +1; } else { for (int i=0; i<space; i++) cout<<" "; } if(curr->data) { //curr is a tree node cout<<curr->data->key; printQueue.enqueue(curr->data->left, curr->isLeading); printQueue.enqueue(curr->data->right); } else { //curr is a hole cout<<" "; printQueue.enqueue(NULL, curr->isLeading); printQueue.enqueue(NULL); } } } AVLNode* AVLTree::insert(int key) { if(root) { //The tree is not empty, resursively insert the key bool heightChanged; AVLNode *newNode = rInsert(key, root, heightChanged); return newNode; } else { //The tree is empty, insert the new node as the tree root return root = new AVLNode(key); } } AVLNode* AVLTree::rInsert(int key, AVLNode* &subRoot, bool &heightChanged) //heightChanged is true is the subtree leaded by subRoot is taller after insertion { if(key == subRoot->key) { cout<<"No duplicate key allowed."<<endl; return NULL; } else if (key < subRoot->key) { if(subRoot->left) { //Recursively insert into subRoot's left subtree AVLNode *newNode = rInsert(key, subRoot->left, heightChanged); if(!heightChanged) return newNode; subRoot->balance--; switch(subRoot->balance) { case -1: break; case 0: heightChanged = false; break; case -2: //subRoot is unbalanced, and it is left heavy if(subRoot->left->balance == -1) //subRoot's left child is also left heavy, case 1 balance1(subRoot); else //subRoot's left child is right heavy, case 2 //Note: subRoot->left->balance can only be 1 or -1 balance2(subRoot); heightChanged = false; break; } return newNode; } else { //Insert as subRoot's left child subRoot->balance--; //The balance of subRoot after insertion can only be -1 or 0 if(subRoot->balance == -1) heightChanged = true; else heightChanged = false; return subRoot->left = new AVLNode(key); } } else { if(subRoot->right) { //Recursively insert into subRoot's right subtree AVLNode *newNode = rInsert(key, subRoot->right, heightChanged); if(!heightChanged) return newNode; subRoot->balance++; switch(subRoot->balance) { case 1: break; case 0: heightChanged = false; break; case 2: //subRoot is unbalanced, and it is right heavy if(subRoot->right->balance == -1) //subRoot's right child is left heavy, case 3 balance3(subRoot); else //subRoot's right child is right heavy, case 4 //Note: subRoot->left->balance can only be 1 or -1 balance4(subRoot); heightChanged = false; break; } return newNode; } else { //Insert as subRoot's right child subRoot->balance++; //The balance of subRoot after insertion can only be 1 or 0 if(subRoot->balance == 1) heightChanged = true; else heightChanged = false; return subRoot->right = new AVLNode(key); } } } AVLNode* AVLTree::remove(int key) { // To judge the balance if it is changed bool heightChanged; if(!root){ cout<<"The tree is empty!"<<endl; } else{ rRemove(key,root,heightChanged); } } AVLNode *AVLTree::rRemove(int key,AVLNode* &subroot, bool &heightChanged){ // When the key equals the current node key if(key==subroot->key){ //Left child is empty if ( subroot->left == NULL && subroot->right != NULL ) { //let temp point to subroot temp=subroot; heightChanged=true; //change subroot value to the right child subroot=subroot->right; //pick the temp from the tree return temp; } //Right child is empty else if ( subroot->right == NULL && subroot->left != NULL) { //let temp point to subroot temp=subroot; heightChanged=true; //change subroot value to the left child subroot=subroot->left; //pick the temp from the tree return temp; } else if(subroot->right == NULL && subroot->left == NULL){ temp=subroot; heightChanged=true; subroot=NULL; return temp; } // Both left and right tree else { temp = findMin( subroot->right, heightChanged); temp->left=subroot->left; temp->right=subroot->right; //change the balance of new subroot as the old one temp->balance=subroot->balance; subroot=temp; if(heightChanged){ subroot->balance--; } if (subroot->balance==-2){ switch(subroot->left->balance){ case -1: balance1(subroot);break; //left-left case 1: balance2(subroot);break; //left-right default: break; } }else if(subroot->balance == 2){ switch(subroot->right->balance){ case 1: balance3(subroot); //right-left case -1: balance4(subroot); //right-right default: break; } } } //delete temp; //get into the left child of subroot and judge if there is the key }else if(key < subroot->key && subroot->left != NULL){ temp=rRemove( key, subroot->left, heightChanged); if(heightChanged){ subroot->balance++; switch(subroot->balance){ case 0: heightChanged=true;break; case 1: heightChanged=false;break; case 2: if(subroot->right->balance == -1){ //subRoot's right child is left heavy, case 3 balance3(subroot); heightChanged=true;break; }else if(subroot->right->balance == 0){ //subRoot's right child is right heavy, case 4 //Note: subRoot->left->balance can only be 1 or -1 balance6(subroot); heightChanged=false;break; //balance 5 and 6 heighted equals false }else{ balance4(subroot); heightChanged=true;break; } } return subroot; } //get into right child and judge if there is the key }else if(key>subroot->key && subroot->right != NULL){ temp = rRemove( key, subroot->right, heightChanged); if(heightChanged){ subroot->balance--; switch(subroot->balance){ case 0: heightChanged=true;break; case -1: heightChanged=false;break; case -2: if(subroot->left->balance == -1){ //subRoot's right child is left heavy, case 3 balance1(subroot); heightChanged=true;break; }else if(subroot->left->balance == 0){ //subRoot's right child is right heavy, case 4 //Note: subRoot->left->balance can only be 1 or -1 balance5(subroot); heightChanged=false;break; }else{ balance2(subroot); heightChanged=true;break; } } return subroot; } }else{ cout<<"这个节点不存在!"<<endl; return NULL; } } //Find the smallest one from the right tree AVLNode * AVLTree::findMin( AVLNode * &subroot, bool &heightChanged) /* Begin of findMin */ { tmp = subroot; if (subroot == NULL){ return NULL; }else if (subroot -> left == NULL && subroot -> right != NULL){ //change the pointer subroot=subroot->right; heightChanged=true; return tmp; } else if(subroot -> left == NULL && subroot -> right == NULL){ heightChanged = true; subroot = NULL; return tmp; }else tmp = findMin(subroot -> left, heightChanged); if(heightChanged){ //right is heavier subroot->balance++; } switch(subroot->balance ){ case 0: heightChanged=true;break; case 1: heightChanged=false;break; case 2: if(subroot->right->balance == -1){ //subRoot's right child is left heavy, case 3 balance3(subroot); heightChanged=true;break; } else if(subroot->right->balance == 1){ //subRoot's right child is right heavy, case 4 //Note: subRoot->left->balance can only be 1 or -1 balance4(subroot); heightChanged=true;break; }else{ //subroot->right->balance == 0 balance6(subroot); heightChanged=false;break; //special case } } return tmp; }/* End of findMin() */ void AVLTree::balance1(AVLNode* &subRoot) { //For a diagram, see slide 13, lecture 10 AVLNode *k1 = subRoot->left, *k2 = subRoot; //fix k2 k2->left = k1->right; k2->balance = 0; //fix k1 k1->right = k2; k1->balance = 0; subRoot = k1; } void AVLTree::balance2(AVLNode* &subRoot) { //For a diagram, see slide 7, lecture 11 AVLNode *k3 = subRoot, *k1 = subRoot->left, *k2 = k1->right; //fix k1 k1->right = k2->left; if(k2->balance == 1) //if k2 is right heavy, then the height of subtree B is 1 smaller than the other subtrees, therefore k1 is left heavy k1->balance = -1; else k1->balance = 0; //fix k3 k3->left = k2->right; if(k2->balance == -1) //if k2 is left heavy, then the height of subtree C is 1 smaller than the other subtrees, therefore k3 is right heavy k3->balance = 1; else k3->balance = 0; //fix k2 k2->left = k1; k2->right = k3; k2->balance = 0; subRoot = k2; } void AVLTree::balance3(AVLNode* &subRoot) { //For a diagram, see slide 8, lecture 11 AVLNode *k1 = subRoot, *k3 = subRoot->right, *k2 = k3->left; //fix k1 k1->right = k2->left; if(k2->balance == 1) //if k2 is right heavy, then the height of subtree B is 1 smaller than the other subtrees, therefore k1 is left heavy k1->balance = -1; else k1->balance = 0; //fix k3 k3->left = k2->right; if(k2->balance == -1) //if k2 is left heavy, then the height of subtree C is 1 smaller than the other subtrees, therefore k3 is right heavy k3->balance = 1; else k3->balance = 0; //fix k2 k2->left = k1; k2->right = k3; k2->balance = 0; subRoot = k2; } void AVLTree::balance4(AVLNode* &subRoot) { //For the diagram, see slide 15, lecture 10 AVLNode *k1 = subRoot, *k2 = subRoot->right; //fix k1 k1->right = k2->left; k1->balance = 0; //fix k2 k2->left = k1; k2->balance = 0; subRoot = k2; } void AVLTree::balance5(AVLNode* &subRoot) { //For a diagram, see slide 13, lecture 10 AVLNode *k1 = subRoot->left, *k2 = subRoot; //fix k2 k2->left = k1->right; //fix k1 k1->right = k2; k1->balance=1; //After the rotation k1 balance is 1, k2 is -1 k2->balance=-1; subRoot = k1; } void AVLTree::balance6(AVLNode* &subRoot) { //For the diagram, see slide 15, lecture 10 AVLNode *k1 = subRoot, *k2 = subRoot->right; //fix k1 k1->right = k2->left; //fix k2 k2->left = k1; k1->balance=1; //After the rotation k1 balance is 1, k2 is -1 k2->balance=-1; subRoot = k2; } int main() { AVLTree tree; char loopFlag = '1'; int i = 8; int removeElement; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 5; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 4; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 2; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 3; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 0; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 15; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 10; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 11; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 17; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); i = 9; cout<<"Inserting "<<i<<endl; tree.insert(i); tree.printTree(); do { cout<<"Please input element you want to remove:"<<endl; cin>>removeElement; tree.remove(removeElement); tree.printTree(); cout<<"\n\n"; cout<<"想继续删除吗?0:退出/1:继续...."<<endl; cin>>loopFlag; }while((loopFlag != '0')); return 0; }
更多精彩
赞助商链接