• 强撸AVL(C++实现


    勉强算CLRS的课后题,就贴在这了

    想不到勉强看懂了算法导论红黑树代码和证明后撸个AVL看别人的代码(有错)都要撸6小时(算上简单的调试),贴代码,不想解释原理,欢迎怼错=

    AvlTree.h

      1 #pragma once
      2 #include <algorithm>
      3 #include <iostream>
      4 //智能指针了解一下,这样就不用自己去delete了
      5 template<class T>
      6 struct Atnode {
      7     Atnode(T value, int height, Atnode* l, Atnode* r) :
      8         key(value), height(height), left(l), right(r){}
      9 
     10     T key;
     11     int height;
     12     Atnode* left;
     13     Atnode* right;
     14 };
     15 
     16 template<class T>
     17 class AvlTree {
     18     friend void print(AvlTree<T>* tree)//非成员函数不能加const修饰符
     19     {
     20         if (tree->Root)tree->_print(tree->Root);
     21     }
     22 public:
     23     AvlTree():Root(nullptr){}
     24     ~AvlTree() { destroy(); }
     25 
     26     void inorder()const;
     27 
     28     void destroy() { destroy(Root); }
     29 
     30     void insert(T key) { Root = insert(Root, key); }
     31     void remove(T key) { Root = remove(Root, key); }
     32 
     33     int height()const { return height(Root); }
     34 
     35 private:
     36     Atnode<T>* Root;
     37 
     38 private:
     39     void _print(Atnode<T>* );
     40     //void inorder(Atnode<T>*)const;
     41     void destroy(Atnode<T>*);
     42     
     43     Atnode<T>* insert(Atnode<T>*, T key);
     44     Atnode<T>* remove(Atnode<T>*, T key);
     45 
     46     Atnode<T>* maxmimun(Atnode<T>*);
     47     Atnode<T>* minimum(Atnode<T>*);
     48     
     49     Atnode<T>* leftrotate(Atnode<T>*);
     50     Atnode<T>* left_right(Atnode<T>*);
     51     Atnode<T>* rightrotate(Atnode<T>*);
     52     Atnode<T>* right_left(Atnode<T>*);
     53     //记得考虑空结点
     54     int height(Atnode<T>*)const;
     55 };
     56 template<class T>
     57 void AvlTree<T>::_print(Atnode<T>* root) {
     58     if (root->left != 0) {
     59         cout << root->left->key << "" << root->key << "的左孩子" << endl;
     60         _print(root->left);
     61     }
     62     if (root->right != 0) {
     63         cout << root->right->key << "" << root->key << "的右孩子" << endl;
     64         _print(root->right);
     65     }
     66 }
     67 
     68 template<class T>
     69 Atnode<T>* AvlTree<T>::insert(Atnode<T>* root, T key) {
     70     if (root == nullptr) {//进行插入
     71         root = new Atnode<T>(key, 0, 0, 0);
     72         return root;
     73     }
     74 
     75     if (root->key == key) {//插入失败
     76         std::cerr << "已存在该节点,默认不进行操作" << endl;
     77         return root;
     78     }
     79 
     80     if (root->key > key) {//递归插入左子树
     81         root->left = insert(root->left, key);
     82         if (height(root->left) - height(root->right) == 2) {
     83             if (height(root->left->right) > height(root->left->left))
     84                 root = left_right(root);
     85             else
     86                 root = rightrotate(root);
     87         }
     88     }
     89     else{
     90         root->right = insert(root->right, key);
     91         if (height(root->right) - height(root->left) == 2) {
     92             if (height(root->right->left) > height(root->right->right))
     93                 root = right_left(root);
     94             else
     95                 root = leftrotate(root);
     96         }
     97     }
     98     root->height = max(height(root->left), height(root->right)) + 1;
     99     return root;
    100 }
    101 
    102 template<class T>
    103 void AvlTree<T>::destroy(Atnode<T>* root) {
    104     if (root == nullptr)return;
    105     destroy(root->left);
    106     destroy(root->right);
    107     delete root;
    108 }
    109 
    110 template<class T>
    111 Atnode<T>* AvlTree<T>::right_left(Atnode<T>* root) {
    112     root->right = rightrotate(root->right);
    113     return leftrotate(root);
    114 }
    115 
    116 template<class T>
    117 Atnode<T>* AvlTree<T>::left_right(Atnode<T>* root) {
    118     root->left = leftrotate(root->left);
    119     return rightrotate(root);
    120 }
    121 
    122 template<class T>
    123 Atnode<T>* AvlTree<T>::leftrotate(Atnode<T>* root) {
    124     Atnode<T>* rc = root->right;
    125     root->right = rc->left;
    126     rc->left = root;
    127     root->height = std::max(height(root->left), height(root->right)) + 1;
    128     rc->height = std::max(root->height, height(rc->right)) + 1;
    129 
    130     return rc;
    131 }
    132 
    133 template<class T>
    134 Atnode<T>* AvlTree<T>::rightrotate(Atnode<T>* root) {
    135     Atnode<T>* lc = root->left;
    136     root->left = lc->right;
    137     lc->right = root;
    138     //更新原根和新根的高度
    139     root->height = std::max(height(root->left), height(root->right)) + 1;
    140     lc->height = std::max(height(lc->left), root->height) + 1;
    141 
    142     return lc;
    143 }
    144 
    145 template<class T>
    146 Atnode<T>* AvlTree<T>::minimum(Atnode<T>*root) {
    147     if (root == nullptr)return 0;
    148     while (root->left)root = root->left;
    149     return root;
    150 }
    151 
    152 template<class T>
    153 Atnode<T>* AvlTree<T>::maxmimun(Atnode<T>* root) {
    154     if (root == nullptr)return 0;
    155     while (root->right)root = root->right;
    156     return root;
    157 }
    158 
    159 
    160 template<class T>
    161 inline
    162 int AvlTree<T>::height(Atnode<T>* n)const {
    163     if (n == nullptr)return -1;
    164     else return n->height;
    165 }
    166 
    167 template<class T>
    168 Atnode<T>* AvlTree<T>::remove(Atnode<T>* root, T key) {
    169     if (root == 0) {
    170         std::cerr << "兄弟,没得删" << endl;
    171         return nullptr;
    172     }
    173 
    174     //删除节点在左子树
    175     if (key < root->key) {
    176         root->left = remove(root->left, key);
    177 
    178         //在左子树删除后可能导致右子树高度过高,相当于在右子树插入新节点
    179         if (height(root->right) - height(root->left) == 2) {
    180             if (height(root->right->right) < height(root->right->left))
    181                 root = right_left(root);
    182             else//else分支实际上包括两种情况
    183                 root = leftrotate(root);
    184         }
    185     }
    186     //删除节点在右子树
    187     else if (key > root->key) {//调用旋转函数记得巴返回值赋给原来的root
    188         root->right = remove(root->right, key);//删除后拼接
    189 
    190         if (height(root->left) - height(root->right) == 2) {
    191             if (height(root->left->right) > height(root->left->left))
    192                 root = left_right(root);
    193             else
    194                 root = rightrotate(root);
    195         }
    196     }
    197     else {//找到删除节点
    198         if (root->left == 0) { 
    199             auto deleted = root;
    200             root = root->right;
    201             delete deleted;
    202         }
    203         else if (root->right == 0) { 
    204             auto deleted = root;
    205             root = root->left;
    206             delete deleted;
    207         }
    208         else {//均不为空,寻找替代root的点,
    209             //可以说左子树的max,也可以是右子树的min
    210             auto replace = root;
    211             //在左子树找替代点
    212             if (height(root->right) < height(root->left)) {
    213                 replace = maxmimun(root->left);
    214 
    215                 if (replace == root->left) {
    216                     auto deleted = root;
    217                     root->left->right = root->right;
    218                     root = root->left;
    219                     delete deleted;
    220                 }
    221                 else {
    222                     root->key = replace->key;
    223                     root->left = remove(root->left, replace->key);
    224                 }
    225             }
    226             else {//在右子树寻找替代点
    227                 replace = minimum(root->right);
    228                 if (replace == root->right) {
    229                     auto deleted = root;
    230                     root->right->left = root->left;
    231                     root = root->right;
    232                     delete deleted;
    233                 }
    234                 else {
    235                     root->key = replace->key;
    236                     root->right = remove(root->right, replace->key);
    237                 }
    238             }
    239         }
    240         //return root;
    241     }//切记更新高度,由于递归,自底向上更新,美妙
    242     if(root)//当节点为NULL时不要更新--
    243         root->height = max(height(root->left), height(root->right)) + 1;
    244     return root;
    245 }

    AvlTreeTest.cpp

     1 #include "AvlTree.h"
     2 
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 int main(void) {
     8     AvlTree<int> xixi;
     9     xixi.insert(3);
    10     xixi.insert(2);
    11     //xixi.insert(6);
    12     //xixi.insert(4);
    13     xixi.insert(5);
    14     xixi.insert(4);
    15 
    16     print(&xixi);
    17     xixi.remove(2);
    18     print(&xixi);
    19 
    20     return 0;
    21 }

    只做了几组简单的测试,发现的小问题都改了,当然可能还有错,望告知,虚心接受批评(逃

  • 相关阅读:
    yii2美化url
    Android 百度地图API 定位 导航
    辛星浅谈PHP的混乱的编码风格
    html5非常火,他究竟与html4有何差别?
    Cocos2d-x 3.0心得(01)-图片载入与混合模式
    解读BOM与COM
    HDU 1718 Rank counting sort解法
    汉语转拼音pinyin4j
    UVALive-6656-Watching the Kangaroo(二分)
    thinPHP中多维数组的遍历
  • 原文地址:https://www.cnblogs.com/schsb/p/8639455.html
Copyright © 2020-2023  润新知