1. 程式人生 > >平衡二叉樹【學習筆記】

平衡二叉樹【學習筆記】

height bsp 長度 template clear 如果 image inf 於平

一、引文

  二叉搜索樹的查找效率取決於平均搜索長度,而這又取決去樹的形狀。當二叉搜索樹退化為一個鏈表時,查找效率非常低。理想的形狀是任何結點的左右子樹的高度最多相差1,而這樣的二叉樹我們也稱之位平衡二叉樹。

二、分析

平衡二叉樹的最核心的地方就在於四種旋轉情況

右旋

即相對根結點的左子樹的高度比右子樹高2,且插入的點為左子樹的左孩子,不滿足條件,所以右旋。

技術分享圖片

先左再右

但如果插入的數是3,如果再只右旋,就會發現有問題,所以這裏需要先以2為根結點左旋再以4為根結點右旋。

技術分享圖片

左旋

即相對根節點的右子樹的高度比左子樹高2,且插入的點為右子樹的右孩子,不滿足條件,所以左旋

技術分享圖片

先右再左

如果插入的為5,那麽如果只左旋也會出現問題,所以先右旋再左旋。

技術分享圖片

三、具體代碼實現

技術分享圖片
  1 #ifndef AVL_H
  2 #define AVL_H
  3 
  4 using namespace std;
  5 
  6 template<class T>
  7 class AvlTree
  8 {
  9 private:
 10     typedef struct AvlNode
 11     {
 12         T data;                           //數據
 13         int
height; //結點深度 14 struct AvlNode *lchild, *rchild; //左右孩子 15 AvlNode(const T &item):data(item),height(0),lchild(NULL),rchild(NULL){} 16 }AvlNode; 17 AvlNode *Root; 18 int size; 19 void R_Rotate(AvlNode * &root); //右旋
20 void L_Rotate(AvlNode * &root); //左旋 21 void LR_Rotate(AvlNode * &root); //先左再右 22 void RL_Rotate(AvlNode * &root); //先右再左 23 int Height(AvlNode * &root){ return (root == NULL?-1:root->height);}; //-1是因為根的深度為0 24 void Print(AvlNode * root); 25 public: 26 AvlTree(void):Root(NULL),size(0){}; 27 ~AvlTree(void){Clear(Root); size = 0;}; 28 void Insert(const T &x, AvlNode * &root); 29 void Insert(const T&x){Insert(x, Root);}; 30 int Size(){return size;}; 31 void Clear(AvlNode *&root); 32 void Print(){Print(Root);puts("");}; 33 34 }; 35 36 template<class T> 37 void AvlTree<T>::R_Rotate(AvlNode * &root) 38 { 39 AvlNode *p = NULL; 40 p = root->lchild; 41 root->lchild = p->rchild; 42 p->rchild = root; 43 root->height = max(Height(root->lchild), Height(root->rchild)) + 1; 44 p->height = max(Height(p->lchild), Height(p->rchild)) + 1; 45 root = p; 46 } 47 template<class T> 48 void AvlTree<T>::L_Rotate(AvlNode * &root) 49 { 50 AvlNode *p = NULL; 51 p = root->rchild; 52 root->rchild = p->lchild; 53 p->lchild = root; 54 root->height = max(Height(root->lchild), Height(root->rchild)) + 1; 55 p->height = max(Height(p->lchild), Height(p->rchild)) + 1; 56 root = p; 57 } 58 template<class T> 59 void AvlTree<T>::LR_Rotate(AvlNode * &root) 60 { 61 L_Rotate(root->lchild); 62 R_Rotate(root); 63 } 64 template<class T> 65 void AvlTree<T>::RL_Rotate(AvlNode * &root) 66 { 67 R_Rotate(root->rchild); 68 L_Rotate(root); 69 } 70 template<class T> 71 void AvlTree<T>::Insert(const T &x, AvlNode * &root) 72 { 73 if(root == NULL) 74 { 75 root = new AvlNode(x); 76 size++; 77 return; 78 } 79 else if(x < root->data) 80 { 81 Insert(x, root->lchild); 82 if(Height(root->lchild) - Height(root->rchild) == 2) 83 { 84 if(x < root->lchild->data) 85 R_Rotate(root); 86 else 87 LR_Rotate(root); 88 } 89 } 90 else if(x > root->data) 91 { 92 Insert(x, root->rchild); 93 if(Height(root->rchild) - Height(root->lchild) == 2) 94 { 95 if(x > root->rchild->data) 96 L_Rotate(root); 97 else 98 RL_Rotate(root); 99 } 100 } 101 root->height = max(Height(root->lchild), Height(root->rchild) ) + 1; 102 103 } 104 105 template<class T> 106 void AvlTree<T>::Clear(AvlNode * &root) 107 { 108 if(root == NULL) 109 return; 110 Clear(root->rchild); 111 Clear(root->lchild); 112 delete root; 113 root = NULL; 114 } 115 116 #endif
View Code

平衡二叉樹【學習筆記】