AVL樹的平衡算法的簡化問題

AVL樹是一種緊湊的二叉查找樹。它的每個結點,都有左右子樹高度相等,或者只相差1這樣的特性。文章https://blog.csdn.net/aaasssdddd96/article/details/106291144給出了一個例子。

為了便于討論,這里對AVL樹的結點平衡情況定義2個名稱,如果兩邊左右子樹高度相等,稱之為真平衡,如果兩邊高度相差1,稱之為準平衡。真平衡和準平衡的這個意義只限于在本文的討論。準平衡有2種情況,所以實際是3種情況。

當AVL樹中插入一個新結點時,它的父結點如果是真平衡,那么狀態轉化為準平衡,樹的高度增加了1,因為高度增加,這個父結點需要接著向更高一層的父結點報告這個變化。

如果父結點是準平衡,那么也有2種情況。如果增加的高度是在較矮的一側,那么父結點狀態轉為真平衡,操作完成;如果增加的高度是在較高的一側,那么結點的平衡因子超限,這種情況在上面第一種情況的最后一個變化發生,需要進行平衡調整。調整之后,恢復為真平衡,局部高度不增,操作完成。

這些問題不難。真正讓初學者感到煩惱的是平衡調整。調整分4種情況,分別稱為“LL-旋轉”,“LR-旋轉”,“RL-旋轉”,“RR-旋轉”。后2種和前兩種鏡像對應。編寫這部分代碼的時候,最好寫完前2種,休息20分鐘,再去復制前面的代碼,逐條改成它的鏡像。休息片刻是為了避免頭暈,轉來轉去轉的頭一暈,修改鏡像時隨便漏掉一條,就會帶來極為費時難調的bug。這樣編程并沒有什么不對,這是需要掌握的基本功,而且實際開發過程也會常常碰到需要蠻力硬搞來攻克的難題。

但在這里是否有比硬搞好一點的辦法?

如果在構造AVL樹時,預分配3個儲備結點會怎么樣。左、中、右,預先結成一個三角形。但不在AVL樹中,而是備用:

struct avl_help {struct node *root;struct triangle {struct node *left;struct node *mid;struct node *right;} help;
};struct avl_help avl;

初始化為:


avl.root=NULL;
avl.help.left = (struct node*)malloc(sizeof(struct node));
avl.help.mid = (struct node*)malloc(sizeof(struct node));
avl.help.right = (struct node*)malloc(sizeof(struct node));avl.help.mid->left=avl.help.left;
avl.help.mid->right=avl.help.right;
avl.help.left->parent=avl.help.mid;
avl.help.right->parent=avl.help.mid;

現在大家都想到了:在AVL樹需要發生平衡調整的時候,把已經調好的3個儲備結點拿出來,整體替換掉樹中需要調整的3個結點,再把替換下來的原來的3個結點做成初始化中的左、中、右三角結構,存回到help中儲備,留給下次用。這樣調整就完成了。而替換下來的3個結點只要把頭結點連到中間結點的左指針,或右指針,具體看那個指針空閑,就重新構成了三角結構。

以“LR型-旋轉”為例,調整操作大致是這樣子。假設ap0,ap1,ap2三個指針已經分別指向LR型的待調整的上中下3個結點:

help= &avl.help;
help->left->left=ap1->left;
help->left->right=ap2->left;
help->left->tag=(ap2->tag==1?0:-1);help->right->left=ap2->right;
help->right->right=ap0->right;
help->right->tag=(ap2->tag==-1?1:0);help->mid->tag=0;
if(help->left->left)
help->left->left->parent=help->left;
if(help->left->right)
help->left->right->parent=help->left;
if(help->right->left)
help->right->left->parent=help->right;
if(help->right->right)
help->right->right->parent=help->right;
help->mid->parent=ap0->parent;if(help->mid->parent==NULL)
avl->root= help->mid;
else if(help->mid->parent->left==ap0)
help->mid->parent->left=help->mid;
else help->mid->parent->right=help->mid;

而存回替換下來的ap0,ap1,ap2三個結點的代碼就是:

ap1->left=ap0;
ap0->parent=ap1;
help->left= ap0;
help->mid=ap1;
help->right=ap2;

其它幾種情況可以類推,大同小異,這里就不重復了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/72309.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/72309.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/72309.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Jenkins 集成DingDing 推送

現狀分析 開發頻繁發布代碼,和測試沒有及時溝通,導致測試返工、bug漏測等 解決方案 Jenkins 集成DingDing機器人,在構建時觸發推送 DingDing端機器人配置 1、在釘釘電腦端建立群聊 2、點擊群右上角設置,點擊【智能群助手】 …

【Quarkus】通過Quarkus集成后端服務示例

說明: REST資源接口(AuthResource)。REST資源實現類(AuthResourceImpl)。服務接口(AuthService)。服務實現類(AuthServiceImpl)。配置文件(application.prop…

硬件驅動——51單片機:獨立按鍵、中斷、定時器/計數器

目錄 一、獨立按鍵 1.原理 2.封裝函數 3.按鍵控制點燈 數碼管 二、中斷 1.原理 2.步驟 3.中斷寄存器IE 4.控制寄存器TCON 5.打開外部中斷0和1 三、定時器/計數器 1.原理 2.控制寄存器TCON 3.工作模式寄存器TMOD 4.按鍵控制頻率的動態閃爍 一、獨立按鍵 1…

基于PMU的14節點、30節點電力系統狀態估計MATLAB程序

“電氣仔推送”獲得資料(專享優惠) 程序簡介: 程序采用三種方法對14節點和30節點電力系統狀態進行評估: ①PMU同步向量測量單元結合加權最小二乘法(WLS)分析電力系統的電壓幅值和相角狀態; …

Apifox Helper 自動生成API接口文檔

在我們開發過程中我們在編寫請求地址和編寫請求參數的時候特別花費時間耗費了我們很多時間,作為一個程序員,更應該把精力時間集中在開發上, Apifox Helper 是 Apifox 團隊針對 IntelliJ IDEA 環境所推出的插件,可以在 IDEA 環境中…

Python 3.13實現數據未來預測功能(詳細功能實現及環境搭建)

目錄 摘要 1. 導入所需庫 2. 加載和查看數據 3. 數據預處理 4. 拆分數據集 5. 模型訓練 6. 模型評估 7. 進行預測 結論 摘要 本文將引導您使用Python 3.13實現數據預測功能。我們將使用常用的Python庫, 如pandas、numpy和sklearn,來幫助讀者快速搭建一個簡…

基于Redis實現限流的幾種方式

限流盡可能在滿足需求的情況下越簡單越好! 分布式限流是指在分布式系統中對請求進行限制,以防止系統過載或濫用資源。以下是常見的分布式限流策略及其實現方式: 1、基于 Redis 的固定窗口限流 原理: 設定一個時間窗口&#xff0…

【前端文件下載實現:多種表格導出方案的技術解析】

前端文件下載實現:多種表格導出方案的技術解析 背景介紹 在企業級應用中,數據導出是一個常見需求,特別是表格數據的導出。在我們的管理系統中,不僅需要支持用戶數據的Excel導出,還需要處理多種格式的表格文件下載&am…

堆概念和結構

1. 二叉樹的順序結構 普通的二叉樹是不適合用數組來存儲的,因為可能會存在大量的空間浪費。而完全二叉樹更適合使用順序結構存儲。現實中通常 把堆使用順序結構的數組來存儲 ,需要注意的是這里的堆和操作系統虛擬進程地址空間中的堆是兩回事&#xff0c…

VUE的腳手架搭建引入類庫

VUE的小白腳手架搭建 真的好久好久自己沒有發布自己博客了,對于一直在做后端開發的我 ,由于社會卷啊卷只好學習下怎么搭建前端,一起學習成長吧~哈哈哈(最終目的,能夠懂并簡易開發) 文章目錄 VUE的小白腳手架搭建1.下載node.js2.安裝vue腳手架3.創建一個項目4.代碼規范約束配置(…

使用 Arduino 和 ThingSpeak 通過互聯網進行實時溫度和濕度監測

使用 ThingSpeak 和 Arduino 通過 Internet 進行溫度和濕度監控 濕度和溫度是許多地方(如農場、溫室、醫療、工業家庭和辦公室)非常常見的測量參數。我們已經介紹了使用 Arduino 進行濕度和溫度測量,并在 LCD 上顯示數據。 在這個物聯網項目中,我們將使用ThingSpeak在互聯…

論文分享:PL-ALF框架實現無人機低紋理環境自主飛行

在室內倉庫、地下隧道等低紋理復雜場景中,無人機依賴視覺傳感器進行自主飛行時,往往會遇到定位精度低、路徑規劃不穩定等難題。針對這一問題,重慶郵電大學計算機學院雷大江教授團隊在IEEE Trans期刊上提出了一種新型自主飛行框架:…

[Java實戰]性能優化qps從1萬到3萬

一、問題背景 ? 事情起因是項目上springboot項目提供的tps達不到客戶要求,除了增加服務器提高tps之外,作為團隊的技術總監,架構師,技術扛把子,本著我不入地獄誰入地獄的原則,決心從代碼上優化,讓客戶享受到飛一般的感覺。雖然大多數編程工作在寫下第一行代碼時已經完成…

如何篩選能實現共享自助健身房“靈活性”的物聯網框架?

共享自助健身房已經成為一種新興的健身方式,這種模式方便快捷,尤其適合i人健身愛好者,市場接受度還是挺好的。對于無人自助式的健身房要想實現靈活性,要挑選什么樣的物聯網框架呢? 1. 支持多種通信協議 共享自助健身…

【后端】【django】拋棄 Django 自帶用戶管理后,能否使用 `simple-jwt`?

拋棄 Django 自帶用戶管理后,能否使用 simple-jwt? 一、結論 是的,即使拋棄了 Django 自帶的用戶管理(AbstractUser 或 AbstractBaseUser),仍然可以使用 django-rest-framework-simplejwt(簡稱…

【量化科普】Correlation,相關性

【量化科普】Correlation,相關性 🚀量化軟件開通 🚀量化實戰教程 在量化投資領域,相關性(Correlation)是一個核心概念,用于衡量兩個變量之間的線性關系強度和方向。簡單來說,它告…

大數據學習(68)- Flink和Spark Streaming

🍋🍋大數據學習🍋🍋 🔥系列專欄: 👑哲學語錄: 用力所能及,改變世界。 💖如果覺得博主的文章還不錯的話,請點贊👍收藏??留言📝支持一…

MCU詳解:嵌入式系統的“智慧之心”

在現代電子設備中, MCU(Microcontroller Unit,微控制器)扮演著至關重要的角色。從智能家居到工業控制,從汽車電子到醫療設備,MCU以其小巧、低功耗和高集成度的特點,成為嵌入式系統的核心組件。 …

(鏈表)24. 兩兩交換鏈表中的節點

給你一個鏈表,兩兩交換其中相鄰的節點,并返回交換后鏈表的頭節點。你必須在不修改節點內部的值的情況下完成本題(即,只能進行節點交換)。 示例 1: 輸入:head [1,2,3,4] 輸出:[2,1,4…

吳恩達機器學習筆記復盤(三)Jupyter NoteBook

Jupyter NoteBook Jupyter是一個開源的交互式計算環境: 特點 交互式編程:支持以單元格為單位編寫和運行代碼,用戶可以實時看到代碼的執行結果,便于逐步調試和理解代碼邏輯。多語言支持:不僅支持Python,還…