日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2021- 10 -13 AVL树的平衡调整(有parent指针) 代码逻辑

發布時間:2025/3/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021- 10 -13 AVL树的平衡调整(有parent指针) 代码逻辑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

AVL平衡調整步驟:
代碼寫的十分潦草而且沒經過測試,看個樂,我認為應該重點看一下沒有parent指針的版本,以及我認為這里重點在于理解過程。

  • 插入結點

  • 找到 插入節點的 的第一個 不平衡的 非父祖先結點
    2.1 循環遍歷插入結點的祖先結點
    2.2 在遍歷的同時判斷該結點是否平衡
    2.3 平衡則更新當前結點的高度,為了下一次判斷是否平衡,不平衡則進行平衡調整

  • 平衡則進行平衡調整
    3.1 判斷三個結點的位置關系(LL,RR,LR,RL)
    3.2 進行平衡
    3.3 維護結點指針
    如果是刪除導致的結點失衡,在afteradd里把break去掉就可以,一直往上查找是否導致了新的祖先結點失衡,反復平衡
    而且無論是添加導致的失衡,還是刪除導致的失衡,修復的過程都是找到失衡結點進行旋轉,旋轉的過程也是一樣的,找兩個更高的子樹結點,判斷LL,RR,進行調整
    更詳細的也可以看看別人寫的筆記
    !!!

  • ****我犯的錯誤::有沒有可能旋轉涉及的三個結點不連在一起? 不可能
    有沒有可能LL RR LR RL之外的情況?? 不可能 ****
    需要注意:旋轉中涉及到的三個結點分別是:第一個失衡非父祖先結點,第一個失衡非父祖先結點的左子結點或右子結點,第一個失衡非父祖先結點的左子結點或右子結點的左子結點或右子結點
    也就是說,我們旋轉這個操作是針對失衡的那個祖先結點,涉及了三個連在一起的結點,而這三個結點不一定是插入結點本身也不一定是插入結點的父結點(除非插入結點和父結點就是和失衡結點連在一起的那種最簡單結構),我初學時總是覺得這三個點可能不在一起,實際上是混淆了平衡調整的目的是對失衡那個結點的調整,而不一定是對插入結點處,因為插入結點可能本身在很大一顆平衡的AVL子樹中。
    所以旋轉的結點是三個相連的結點,自然只有這四種情況

    //!二叉搜索樹的添加刪除,搜索操作的時間復雜度跟樹的高度有關,為O(h)(相比線性表的O(n)搜索以及添加的話) //! 滿二叉樹的高度基本是logn,所以滿的二叉搜索樹的時間復雜度也接近O(logn) //! 但是如果二叉搜索樹建立的順序,輸入是一個有序數組的話,比如1,2,3,4,5,。。。n這樣建立的二叉搜索樹高度就等于n //! 也就是最壞時間復雜度等于O(n),被稱為二叉搜索樹退化為鏈表 //! 所以我們要盡力維持時間復雜度在O(h)而不是O(n)//! 平衡的概念:二叉樹結點數量固定,左右子樹高度越接近就越平衡,完全二叉樹和滿二叉樹是最平衡的//! 所以如何改進我們的二叉搜索樹?? //! 1.改變添加刪除的元素順序,簡介控制樹的高度 2.改善添加元素后的二叉樹,使之更平衡 //! 我們設計的二叉搜索樹是給別人用的,所以添加刪除的順序,我們無法改變,所以我們只能從添加后的二叉樹的平衡改進入手 //! 一顆達到適度平衡的二叉搜索樹 ,我們稱之為平衡二叉搜索樹 比如:AVL樹,紅黑樹 //! AVL樹是以其發明者命名的,發明者是一個蘇聯科學家,AVL樹是最早發明的自平衡二叉搜索樹之—,搜索、添加、刪除的時間復雜度是O(logn)O(logn) //! 平衡因子:該結點平衡因子等于左子樹高度減去右子樹高度,絕對值小于等于1,即超過1或小于-1,即為失衡,就要自動調整 #include <iostream> #include "queue" #include "stack" #include <string> #include <algorithm> using namespace std; class AVLNode { public:int element;int height;AVLNode *left;AVLNode *right;AVLNode *parent;AVLNode(){this->element = 0;this->left = nullptr;this->right = nullptr;this->parent = nullptr;this->height = 1;}AVLNode(int element){this->element = element;this->left = nullptr;this->right = nullptr;this->parent = nullptr;this->height = 0;} };class AVLtreeZH { private:int size;public://我這里把根節點寫成public了,主要后面寫一些函數可以方便點AVLNode *root = nullptr;void add(int element); //添加元素void afterAdd(AVLNode *node); //! 添加后判斷是否進行以及高度更新 //平衡步驟//什么時候更新結點高度bool isBalanced(AVLNode *node); //! 判斷一個結點是否平衡int balanceFactor(AVLNode *node); //! 獲取一個結點的平衡因子void balancing(AVLNode *node); //! 如何判別平衡操作的類型(RR,LL,LR,RL)AVLNode *heigherChild(AVLNode *node); //! 返回左右子樹中高度較高的那個子結點int getHeight(AVLNode *node); //! 通過左右子樹的height值,返回當前結點的高度void rotateRight(AVLNode *node1); //! 以node1右旋void rotateLeft(AVLNode *node1); //! 以node1左旋 };void AVLtreeZH::afterAdd(AVLNode *node) {while (node->parent != nullptr){node = node->parent;if (isBalanced(node)){node->height = getHeight(node); //更新結點高度continue;}else{balancing(node);break; //如果是刪除導致的結點失衡,這里把break去掉就可以了,一直往上查找是否導致了新的祖先結點失衡}} }void AVLtreeZH::balancing(AVLNode *node1) {AVLNode *node2 = heigherChild(node1);AVLNode *node3 = heigherChild(node2);if (node2 == node1->left && node3 == node2->left){ //LL情況rotateRight(node1);}if (node2 == node1->left && node3 == node2->right){ //LR情況rotateLeft(node2);rotateRight(node1);}if (node2 == node1->right && node3 == node2->right){ //RR情況rotateLeft(node1);}if (node2 == node1->right && node3 == node2->left){ //RL情況rotateRight(node2);rotateLeft(node1);} }void AVLtreeZH::rotateRight(AVLNode *node1) {AVLNode *node2 = heigherChild(node1);AVLNode *node3 = heigherChild(node2);AVLNode *noderoot = node1->parent;node1->left = node2->right; //核心就這兩句node2->right = node1;node1->parent = node2; //維護父結點指針node2->parent = noderoot;if (node1->left != nullptr){node1->left->parent = node1;}if (noderoot == nullptr){}else if (node1 == noderoot->left){node2 = noderoot->left;}else if (node1 == noderoot->right){node2 = noderoot->right;}node1->height = getHeight(node1);node2->height = getHeight(node2);node3->height = getHeight(node3);if (noderoot != nullptr){noderoot->height = getHeight(noderoot);} }void AVLtreeZH::rotateLeft(AVLNode *node1) {//和右旋一個路子 }bool AVLtreeZH::isBalanced(AVLNode *node) //判斷結點是否平衡,其實就是看平衡因子絕對值有沒有大于等于2 {int i = balanceFactor(node);if (i < -1 || i > 1){return false;}else if (-1 <= i <= 1){return true;} }int AVLtreeZH::getHeight(AVLNode *node) {if (node->left->height >= node->right->height){return (node->left->height + 1);}else{return (node->right->height + 1);} }int AVLtreeZH::balanceFactor(AVLNode *node) {return getHeight(node->left) - getHeight(node->right); }AVLNode *AVLtreeZH::heigherChild(AVLNode *node) {int leftheight;int rightheight;if (node->left == nullptr){leftheight = 0;}if (node->right == nullptr){rightheight = 0;}if (leftheight == 0 && rightheight == 0){return nullptr;}if (leftheight > rightheight){return node->left;}else if (leftheight < rightheight){return node->right;} }

    總結

    以上是生活随笔為你收集整理的2021- 10 -13 AVL树的平衡调整(有parent指针) 代码逻辑的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。