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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

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

AVL平衡調(diào)整步驟:
代碼寫(xiě)的十分潦草而且沒(méi)經(jīng)過(guò)測(cè)試,看個(gè)樂(lè),我認(rèn)為應(yīng)該重點(diǎn)看一下沒(méi)有parent指針的版本,以及我認(rèn)為這里重點(diǎn)在于理解過(guò)程。

  • 插入結(jié)點(diǎn)

  • 找到 插入節(jié)點(diǎn)的 的第一個(gè) 不平衡的 非父祖先結(jié)點(diǎn)
    2.1 循環(huán)遍歷插入結(jié)點(diǎn)的祖先結(jié)點(diǎn)
    2.2 在遍歷的同時(shí)判斷該結(jié)點(diǎn)是否平衡
    2.3 平衡則更新當(dāng)前結(jié)點(diǎn)的高度,為了下一次判斷是否平衡,不平衡則進(jìn)行平衡調(diào)整

  • 平衡則進(jìn)行平衡調(diào)整
    3.1 判斷三個(gè)結(jié)點(diǎn)的位置關(guān)系(LL,RR,LR,RL)
    3.2 進(jìn)行平衡
    3.3 維護(hù)結(jié)點(diǎn)指針
    如果是刪除導(dǎo)致的結(jié)點(diǎn)失衡,在afteradd里把break去掉就可以,一直往上查找是否導(dǎo)致了新的祖先結(jié)點(diǎn)失衡,反復(fù)平衡
    而且無(wú)論是添加導(dǎo)致的失衡,還是刪除導(dǎo)致的失衡,修復(fù)的過(guò)程都是找到失衡結(jié)點(diǎn)進(jìn)行旋轉(zhuǎn),旋轉(zhuǎn)的過(guò)程也是一樣的,找兩個(gè)更高的子樹(shù)結(jié)點(diǎn),判斷LL,RR,進(jìn)行調(diào)整
    更詳細(xì)的也可以看看別人寫(xiě)的筆記
    !!!

  • ****我犯的錯(cuò)誤::有沒(méi)有可能旋轉(zhuǎn)涉及的三個(gè)結(jié)點(diǎn)不連在一起? 不可能
    有沒(méi)有可能LL RR LR RL之外的情況?? 不可能 ****
    需要注意:旋轉(zhuǎn)中涉及到的三個(gè)結(jié)點(diǎn)分別是:第一個(gè)失衡非父祖先結(jié)點(diǎn),第一個(gè)失衡非父祖先結(jié)點(diǎn)的左子結(jié)點(diǎn)或右子結(jié)點(diǎn),第一個(gè)失衡非父祖先結(jié)點(diǎn)的左子結(jié)點(diǎn)或右子結(jié)點(diǎn)的左子結(jié)點(diǎn)或右子結(jié)點(diǎn)
    也就是說(shuō),我們旋轉(zhuǎn)這個(gè)操作是針對(duì)失衡的那個(gè)祖先結(jié)點(diǎn),涉及了三個(gè)連在一起的結(jié)點(diǎn),而這三個(gè)結(jié)點(diǎn)不一定是插入結(jié)點(diǎn)本身也不一定是插入結(jié)點(diǎn)的父結(jié)點(diǎn)(除非插入結(jié)點(diǎn)和父結(jié)點(diǎn)就是和失衡結(jié)點(diǎn)連在一起的那種最簡(jiǎn)單結(jié)構(gòu)),我初學(xué)時(shí)總是覺(jué)得這三個(gè)點(diǎn)可能不在一起,實(shí)際上是混淆了平衡調(diào)整的目的是對(duì)失衡那個(gè)結(jié)點(diǎn)的調(diào)整,而不一定是對(duì)插入結(jié)點(diǎn)處,因?yàn)椴迦虢Y(jié)點(diǎn)可能本身在很大一顆平衡的AVL子樹(shù)中。
    所以旋轉(zhuǎn)的結(jié)點(diǎn)是三個(gè)相連的結(jié)點(diǎn),自然只有這四種情況

    //!二叉搜索樹(shù)的添加刪除,搜索操作的時(shí)間復(fù)雜度跟樹(shù)的高度有關(guān),為O(h)(相比線(xiàn)性表的O(n)搜索以及添加的話(huà)) //! 滿(mǎn)二叉樹(shù)的高度基本是logn,所以滿(mǎn)的二叉搜索樹(shù)的時(shí)間復(fù)雜度也接近O(logn) //! 但是如果二叉搜索樹(shù)建立的順序,輸入是一個(gè)有序數(shù)組的話(huà),比如1,2,3,4,5,。。。n這樣建立的二叉搜索樹(shù)高度就等于n //! 也就是最壞時(shí)間復(fù)雜度等于O(n),被稱(chēng)為二叉搜索樹(shù)退化為鏈表 //! 所以我們要盡力維持時(shí)間復(fù)雜度在O(h)而不是O(n)//! 平衡的概念:二叉樹(shù)結(jié)點(diǎn)數(shù)量固定,左右子樹(shù)高度越接近就越平衡,完全二叉樹(shù)和滿(mǎn)二叉樹(shù)是最平衡的//! 所以如何改進(jìn)我們的二叉搜索樹(shù)?? //! 1.改變添加刪除的元素順序,簡(jiǎn)介控制樹(shù)的高度 2.改善添加元素后的二叉樹(shù),使之更平衡 //! 我們?cè)O(shè)計(jì)的二叉搜索樹(shù)是給別人用的,所以添加刪除的順序,我們無(wú)法改變,所以我們只能從添加后的二叉樹(shù)的平衡改進(jìn)入手 //! 一顆達(dá)到適度平衡的二叉搜索樹(shù) ,我們稱(chēng)之為平衡二叉搜索樹(shù) 比如:AVL樹(shù),紅黑樹(shù) //! AVL樹(shù)是以其發(fā)明者命名的,發(fā)明者是一個(gè)蘇聯(lián)科學(xué)家,AVL樹(shù)是最早發(fā)明的自平衡二叉搜索樹(shù)之—,搜索、添加、刪除的時(shí)間復(fù)雜度是O(logn)O(logn) //! 平衡因子:該結(jié)點(diǎn)平衡因子等于左子樹(shù)高度減去右子樹(shù)高度,絕對(duì)值小于等于1,即超過(guò)1或小于-1,即為失衡,就要自動(dòng)調(diào)整 #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://我這里把根節(jié)點(diǎn)寫(xiě)成public了,主要后面寫(xiě)一些函數(shù)可以方便點(diǎn)AVLNode *root = nullptr;void add(int element); //添加元素void afterAdd(AVLNode *node); //! 添加后判斷是否進(jìn)行以及高度更新 //平衡步驟//什么時(shí)候更新結(jié)點(diǎn)高度bool isBalanced(AVLNode *node); //! 判斷一個(gè)結(jié)點(diǎn)是否平衡int balanceFactor(AVLNode *node); //! 獲取一個(gè)結(jié)點(diǎn)的平衡因子void balancing(AVLNode *node); //! 如何判別平衡操作的類(lèi)型(RR,LL,LR,RL)AVLNode *heigherChild(AVLNode *node); //! 返回左右子樹(shù)中高度較高的那個(gè)子結(jié)點(diǎn)int getHeight(AVLNode *node); //! 通過(guò)左右子樹(shù)的height值,返回當(dāng)前結(jié)點(diǎn)的高度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); //更新結(jié)點(diǎn)高度continue;}else{balancing(node);break; //如果是刪除導(dǎo)致的結(jié)點(diǎn)失衡,這里把break去掉就可以了,一直往上查找是否導(dǎo)致了新的祖先結(jié)點(diǎn)失衡}} }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; //維護(hù)父結(jié)點(diǎn)指針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) {//和右旋一個(gè)路子 }bool AVLtreeZH::isBalanced(AVLNode *node) //判斷結(jié)點(diǎn)是否平衡,其實(shí)就是看平衡因子絕對(duì)值有沒(méi)有大于等于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;} }

    總結(jié)

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

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。