当前位置:   article > 正文

平衡二叉树的建立查考插入删除操作_平衡二叉树的应用 实现平衡二叉树的构造,检索,插入和删除功能:

平衡二叉树的应用 实现平衡二叉树的构造,检索,插入和删除功能:

      如果二叉排序树的左、右子树的高度之差的绝对值不超过1,这样的排序二叉树称为平衡二叉树,它的平均查找长度达到O(log2n)。

      为了避免树的高度增长过快,降低二叉排序树的性能,我们规定在插入和删除二叉树结点时,要保证任意结点的左、右子树高度差的绝对值不超过1。这样的二叉树称为平衡二叉树。

      平衡二叉树可定义为它或是一棵空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的高度差的绝对值不超过1。

     需要注意的有以下两点:

插入操作中:

      LR和RL旋转的时候,调用LL和RR旋转,其原因是这样做复合LR和RL的最终要求,这里调用LL(RR)旋转函数,不是说

在左子树的左子树(右子树的右子树)插入了结点,而只是为了可以达到LR(RL)的最终形态。这里也可以不调用LL和RR函数,对指针进行操作也可以,不过需要对四代指针进行操作,比较麻烦。

删除操作(难点):

      同插入操作一样,删除结点时也有可能破坏平衡性,这就要求我们删除的时候要进行平衡性调整。

      删除分为以下几种情况:

      首先在整个二叉树中搜索要删除的结点,如果没搜索到直接返回不作处理,否则执行以下操作:

           1.要删除的节点是当前根节点T。

             如果左右子树都非空。在高度较大的子树中实施删除操作。

                分两种情况:

                 (1)、左子树高度大于右子树高度,将左子树中最大的那个元素赋给当前根节点,然后删除左子树中元素值最大的那个节点。

                  (2)、左子树高度小于右子树高度,将右子树中最小的那个元素赋给当前根节点,然后删除右子树中元素值最小的那个节点。

             如果左右子树中有一个为空,那么直接用那个非空子树或者是NULL替换当前根节点即可。

          2、要删除的节点元素值小于当前根节点T值,在左子树中进行删除。

               递归调用,在左子树中实施删除。这个是需要判断当前根节点是否仍然满足平衡条件,如果满足平衡条件,只需要更新当前根节点T的高度信息。否则,需要进行旋转调整:如果T的左子节点的左子树的高度大于T的左子节点的右子树的高度,进行相应的单旋转。否则进行双旋转。

           3、要删除的节点元素值大于当前根节点T值,在右子树中进行删除。

  1. #include <iostream>
  2. #include <queue>
  3. #include <stack>
  4. using namespace std;
  5. template <typename T>
  6. struct avlTreeNode{
  7. T data;
  8. int height;
  9. avlTreeNode* left;
  10. avlTreeNode* right;
  11. avlTreeNode(T val, avlTreeNode<T>* l, avlTreeNode<T>* r):data(val), height(0), left(l), right(r){}
  12. };
  13. template <typename T>
  14. class avlTree{
  15. private:
  16. avlTreeNode<T>* root;
  17. int max(int a, int b){return a > b ? a : b;}
  18. public:
  19. avlTree(){root = NULL;}
  20. avlTreeNode<T>*& getRoot(){return root;}
  21. int getHeight(avlTreeNode<T>* ptr);//获得子树的高度
  22. void llRotation(avlTreeNode<T>* &root);//对以root为根节点的最小不平衡子树进行LL平衡旋转
  23. void lrRotation(avlTreeNode<T>* &root);//对以root为根节点的最小不平衡子树进行LR平衡旋转
  24. void rrRotation(avlTreeNode<T>* &root);//对以root为根节点的最小不平衡子树进行RR平衡旋转
  25. void rlRotation(avlTreeNode<T>* &root);//对以root为根节点的最小不平衡子树进行RL平衡旋转
  26. void addValue(avlTreeNode<T>* &root, T val);//向平衡树中增加结点
  27. void delValue(avlTreeNode<T>* &root, T val);//删除值val所在结点
  28. void creatAvlTree();//建立平衡树
  29. avlTreeNode<T>* getMin(avlTreeNode<T>* root) const;//找到以root为根节点的树中最小的节点
  30. avlTreeNode<T>* getMax(avlTreeNode<T>* root) const;//找到以root为根节点的树中最大的节点
  31. void printAvlTreeOfPre() const;//先序遍历输出结果
  32. void printAvlTreeOfIn() const;//中序遍历输出结果
  33. };
  34. template <typename T>
  35. int avlTree<T>::getHeight(avlTreeNode<T>* ptr){
  36. if(ptr != NULL)
  37. return ptr -> height;
  38. return 0;
  39. }
  40. template <typename T>
  41. void avlTree<T>::llRotation(avlTreeNode<T>* &root){
  42. //进行右单旋转,这里需要注意的是需要对两个结点的高度进行调整
  43. avlTreeNode<T>* temp = root;
  44. root = root -> left;
  45. temp -> left = root -> right;
  46. root -> right = temp;
  47. temp -> height = max(getHeight(temp -> left), getHeight(temp -> right)) + 1;
  48. root -> height = max(getHeight(root -> left), getHeight(root -> right)) + 1;
  49. }
  50. template <typename T>
  51. void avlTree<T>::rrRotation(avlTreeNode<T>* &root){
  52. //进行左单旋转,这里需要注意的是需要对两个结点的高度进行调整
  53. avlTreeNode<T>* temp = root;
  54. root = root -> right;
  55. temp -> right = root -> left;
  56. root -> left = temp;
  57. temp -> height = max(getHeight(temp -> left), getHeight(temp -> right)) + 1;
  58. root -> height = max(getHeight(root -> left), getHeight(root -> right)) + 1;
  59. }
  60. template <typename T>
  61. void avlTree<T>::lrRotation(avlTreeNode<T>* &root){
  62. //先进行左旋转,在进行右旋转
  63. rrRotation(root -> left);
  64. llRotation(root);
  65. }
  66. template <typename T>
  67. void avlTree<T>::rlRotation(avlTreeNode<T>* &root){
  68. //先进行左旋转,在进行右旋转
  69. llRotation(root -> right);
  70. rrRotation(root);
  71. }
  72. template <typename T>
  73. void avlTree<T>::addValue(avlTreeNode<T>* &root, T val){
  74. if(root == NULL){//根节点是NULL
  75. root = new avlTreeNode<T>(val, NULL, NULL);
  76. }else if(root -> data > val){//插入到左子树
  77. addValue(root -> left, val);
  78. if(getHeight(root -> left) - getHeight(root -> right) == 2){
  79. if(root -> left -> data > val){
  80. llRotation(root);
  81. }else{
  82. lrRotation(root);
  83. }
  84. }
  85. }else if(root -> data < val){//插入到右子树
  86. addValue(root -> right, val);
  87. if(getHeight(root -> left) - getHeight(root -> right) == -2){
  88. if(root -> right -> data > val){
  89. rlRotation(root);
  90. }else{
  91. rrRotation(root);
  92. }
  93. }
  94. }else{
  95. cout << "平衡树中已有该结点" <<endl;
  96. }
  97. root -> height = getHeight(root -> left) > getHeight(root -> right) ? getHeight(root -> left) + 1:getHeight(root -> right) + 1;
  98. }
  99. template <typename T>
  100. void avlTree<T>::creatAvlTree(){
  101. T val;
  102. cin >> val;
  103. while(val != '#'){
  104. addValue(root, val);
  105. cin >> val;
  106. }
  107. }
  108. template <typename T>
  109. void avlTree<T>::delValue(avlTreeNode<T>* &root, T val){
  110. if(root == NULL)//树中没有值为val的节点
  111. return;
  112. if(root -> data == val){
  113. if(root -> left != NULL && root -> right != NULL){
  114. //左子树高度大,删除左子树中值最大的结点,将其赋给根结点
  115. if(getHeight(root -> left) > getHeight(root -> right)){
  116. root -> data = getMax(root -> left) -> data;
  117. delValue(root -> left, root -> data);
  118. }else{//右子树高度更大,删除右子树中值最小的结点,将其赋给根结点
  119. root -> data = getMin(root -> right) -> data;
  120. delValue(root -> right, root -> data);
  121. }
  122. }else{//左右子树有一个不为空,直接用需要删除的结点的子结点替换即可
  123. avlTreeNode<T>* temp = root;
  124. root = root -> left == NULL ? root -> right: root -> left;
  125. delete temp;
  126. }
  127. }else if(root -> data < val){//在root的右子树删除val
  128. delValue(root -> right, val);
  129. if(getHeight(root -> right) - getHeight(root -> left) == -2){//需要进行调整
  130. if(getHeight(root -> left -> left) > getHeight(root -> left -> right)){
  131. llRotation(root);
  132. }else{
  133. lrRotation(root);
  134. }
  135. }else{//不需要调整
  136. root -> height = max(getHeight(root -> right), getHeight(root -> left)) + 1;
  137. }
  138. }else if(root -> data > val){//在root的左子树删除val
  139. delValue(root -> left, val);
  140. if(getHeight(root -> right) - getHeight(root -> left) == 2)
  141. {//需要进行调整
  142. if(getHeight(root -> right -> left) > getHeight(root -> right -> right)){
  143. rlRotation(root);
  144. }else{
  145. rrRotation(root);
  146. }
  147. }else{//不需要调整
  148. root -> height = max(getHeight(root -> right), getHeight(root -> left)) + 1;
  149. }
  150. }
  151. }
  152. template <typename T>
  153. avlTreeNode<T>* avlTree<T>::getMin(avlTreeNode<T>* root) const{//找到以root为根节点的树中最小的节点
  154. if(root == NULL)
  155. return NULL;
  156. while(root -> left != NULL){
  157. root = root -> left;
  158. }
  159. return root;
  160. }
  161. template <typename T>
  162. avlTreeNode<T>* avlTree<T>::getMax(avlTreeNode<T>* root) const{//找到以root为根节点的树中最大的节点
  163. if(root == NULL)
  164. return NULL;
  165. while(root -> right != NULL){
  166. root = root -> right;
  167. }
  168. return root;
  169. }
  170. template <typename T>
  171. void avlTree<T>::printAvlTreeOfPre() const{
  172. if(root == NULL)
  173. return;
  174. stack <avlTreeNode<T>*> stc;
  175. stc.push(root);
  176. while(!stc.empty()){
  177. avlTreeNode<T>* temp = stc.top();
  178. stc.pop();
  179. cout << temp -> data << " ";
  180. if(temp -> right != NULL){
  181. stc.push(temp -> right);
  182. }
  183. if(temp -> left != NULL){
  184. stc.push(temp -> left);
  185. }
  186. }
  187. }
  188. template <typename T>
  189. void avlTree<T>::printAvlTreeOfIn() const{
  190. if(root == NULL)
  191. return;
  192. stack <avlTreeNode<T>*> stc;
  193. avlTreeNode<T>* temp = root;
  194. while(!stc.empty() || temp != NULL){
  195. if(temp != NULL){
  196. stc.push(temp);
  197. temp = temp -> left;
  198. }else{
  199. temp = stc.top();
  200. stc.pop();
  201. cout << temp -> data << " ";
  202. temp = temp -> right;
  203. }
  204. }
  205. }
  206. int main(){
  207. avlTree<char>* tree = new avlTree<char>;
  208. tree -> creatAvlTree();
  209. cout<<endl<<"前序遍历结果:"<<endl;
  210. tree -> printAvlTreeOfPre();
  211. cout<<endl<<"中序遍历结果:"<<endl;
  212. tree -> printAvlTreeOfIn();
  213. cout<<endl;
  214. tree -> delValue(tree -> getRoot(), 'a');
  215. cout<<endl<<"删除结点a之后的前序遍历结果:"<<endl;
  216. tree -> printAvlTreeOfPre();
  217. cout<<endl<<"删除结点a之后的中序遍历结果:"<<endl;
  218. tree -> printAvlTreeOfIn();
  219. cout<<endl;
  220. return 0;
  221. }

测试结果如下:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/528407
推荐阅读
相关标签
  

闽ICP备14008679号