【C++】AVL樹(平衡二叉樹)

目錄

  • 一、AVL樹的定義
  • 二、AVL樹的作用
  • 三、AVL樹的插入操作
    • 插入——平衡因子的更新
    • 插入——左單旋
    • 插入——右單旋
    • 插入——左右雙旋
    • 插入——右左雙旋
  • 四、ALVL樹的驗證
  • 五、AVL樹的性能

一、AVL樹的定義

AVL樹,全稱 平衡二叉搜索(排序)樹

二叉搜索樹雖可以縮短查找的效率,但如果數據有序或接近有序二叉搜索樹將退化為單支樹,查找元素相當于在順序表中搜索元素,效率低下。因此,兩位俄羅斯的數學家G.M.Adelson-Velskii和E.M.Landis在1962年發明了一種解決上述問題的方法:當向二叉搜索樹中插入新結點后,如果能保證每個結點的左右子樹高度之差的絕對值不超過1(需要對樹中的結點進行調整),即可降低樹的高度,從而減少平均搜索長度。

平衡因子(Balance Factor,簡寫為bf)
平衡因子(bf):結點的左子樹的深度減去右子樹的深度。也可以是右子樹的深度減去左子樹的深度。看個人實現而異。

即: 結點的平衡因子 = 左子樹的高度 - 右子樹的高度。
或者 節點的平衡因子 = 右子樹的高度 - 左子樹的高度。

AVL樹本質上是一顆二叉查找樹,但是它又具有以下特點:

  • 它的左右子樹都是AVL樹
  • 左右子樹高度之差(簡稱平衡因子)的絕對值不超過1(-1/0/1)

這就是一顆AVL樹
在這里插入圖片描述

二、AVL樹的作用

有一顆二叉樹,他有n個節點,如果他是一顆二叉搜索樹,他形狀多樣,可能會形成單枝樹,高度為n,那么在這顆搜索樹中查找元素的最壞時間復雜度為O(n),最好時間復雜度是O( l o g 2 n log_2 n log2?n)。
如果他是一顆AVL樹,他的高度穩定為 l o g 2 n log_2 n log2?n,查找元素的時間復雜度為O( l o g 2 n log_2 n log2?n)。在這里插入圖片描述
由上圖可知,同樣的結點,由于插入方式不同導致樹的高度也有所不同。特別是在帶插入結點個數很多且正序的情況下,會導致二叉樹的高度是O(N),而AVL樹就不會出現這種情況,樹的高度始終是O(lgN).高度越小,對樹的一些基本操作的時間復雜度就會越小。這也就是我們引入AVL樹的原因。

三、AVL樹的插入操作

插入——平衡因子的更新

在插入一個元素的時候,必然會引起平衡因子的變化,所以我們需要在插入的時候把平衡因子同時更新,在平衡因子大于1或者小于-1時,我們則需要進行旋轉操作,進行調整,使平衡因子再次正常,從而保證這顆二叉樹一直是一顆AVL樹。
?
使用平衡因子計算: 右子樹高度 - 左子樹高度

情況一:
在這里插入圖片描述
在插入元素后,需要更新父節點的平衡因子,在父節點的左子樹插入元素,父節點的平衡因子-1,在父節點的左子樹插入元素,父節點的平衡因子+1,如果父節點的平衡因子更新過后變為1或者-1,則需繼續往上更新至根節點,因為1或者-1表示該節點的高度發生改變,需往上更新。

情況2:
在這里插入圖片描述
在插入元素后,需要更新父節點的平衡因子,在父節點的左子樹插入元素,父節點的平衡因子-1,在父節點的左子樹插入元素,父節點的平衡因子+1,如果父節點的平衡因子更新過后變為0,則不需要繼續向上更新,因為變為0只能說明該樹高度沒有變化,只是相對于原來變得平衡。

如果在更新平衡因子后,平衡因子不在(-1/0/1)范圍時,則需旋轉操作,下面講解如何進行旋轉操作

由于插入需要旋轉的情況較多,大致可以分為四大類

插入——左單旋

動圖演示
請添加圖片描述

情況一
右子樹高時,在右子樹的右側插入元素,此時需要左單旋這里是引用

插入——右單旋

動圖演示
請添加圖片描述

情況二、
左子樹較高時,在左子樹的左側插入元素,此時需要右單旋這里是引用

插入——左右雙旋

情況三、左子樹較高時,在左子樹的右側插入元素,此時需要左右雙旋,即:先對30進行左單旋,然后再對90進行右單旋這里是引用

插入——右左雙旋

情況四、右子樹較高時,在右子樹的左側插入元素,此時需要右左雙旋,即:先對90進行右單旋,然后再對30進行左單旋
在這里插入圖片描述

四、ALVL樹的驗證

int _Height(Node* root)
{//用來計算二叉樹的高度if (root == NULL)return 0;int leftH = _Height(root->_left);int rightH = _Height(root->_right);return leftH > rightH ? leftH + 1 : rightH + 1;
}bool _IsBalance(Node* root)
{if (root == NULL)return true;int leftH = _Height(root->_left);int rightH = _Height(root->_right);//檢查平衡因子if (rightH - leftH != root->_bf){cout << root->_kv.first << "節點平衡因子異常" << endl;return false;}//通過計算左右子樹的高度差判斷這顆二叉樹是否為AVL樹return abs(leftH - rightH) < 2&& _IsBalance(root->_left)&& _IsBalance(root->_right);//檢查高度差要檢查二叉樹中所有節點的左右子樹的高度差
}bool IsBalance()
{return _IsBalance(_root);
}

五、AVL樹的性能

AVL樹是一棵絕對平衡的二叉搜索樹,其要求每個節點的左右子樹高度差的絕對值都不超過1,這樣可以保證查詢時高效的時間復雜度,即 l o g 2 n log_2 n log2?n

但是如果要對AVL樹做一些結構修改的操作,性能非常低下,比如:插入時要維護其絕對平衡,旋轉的次數比較多,更差的是在刪除時,有可能一直要讓旋轉持續到根的位置。因此:如果需要一種查詢高效且有序的數據結構,而且數據的個數為靜態的(即不會改變),可以考慮AVL樹,但一個結構經常修改,就不太適合。

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

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

相關文章

一次Linux圖形化界面恢復

一次Linux 圖形化界面恢復 一次Linux 圖形化界面恢復出現問題場景問題排查 一次Linux 圖形化界面恢復 出現問題場景 使用xmanager遠程連接虛機的CentOS7系統圖形界面出現已拒絕x11轉移申請問題&#xff0c;在折騰X11過程中&#xff0c;安裝與卸載的過程中不小心把xorg-x11-xa…

HCIP的交換機實驗

題目 拓撲圖 PC1/3接口用access 創建WLAN LSW1 創建WLAN [lsw1]vlan batch 2 to 6[lsw1-Ethernet0/0/1]p [lsw1-Ethernet0/0/1]port l [lsw1-Ethernet0/0/1]port link- [lsw1-Ethernet0/0/1]port link-flap [lsw1-Ethernet0/0/1]port link-type acc [lsw1-Ethernet0/0…

kubeasz在線安裝K8S集群單master集群(kubeasz安裝之二)

一、介紹 Kubeasz 是一個基于 Ansible 自動化工具&#xff0c;用于快速部署和管理 Kubernetes 集群的工具。它支持快速部署高可用的 Kubernetes 集群&#xff0c;支持容器化部署&#xff0c;可以方便地擴展集群規模&#xff0c;支持多租戶&#xff0c;提供了強大的監控和日志分…

Bigemap Pro國產基礎軟件介紹——一款多源數據處理軟件

一、軟件簡介 Bigemap Pro是由成都比格圖數據處理有限公司(下稱”BIGEMAP”)開發和發行的國產大數據處理基礎軟件。Bigemap Pro是在BIGEMAP GIS Office基礎上&#xff0c;經過十年的用戶積累與反饋和技術更新迭代出的新一代基礎軟件產品。Bigemap Pro國產基礎軟件集成了數據采…

【Diffusion】李宏毅2023機器學習Diffusion筆記

文章目錄 1 想法概述2 實際過程階段1 Add Noise階段2 Denoise 3 數學原理4 為什么推理時要額外加入noise5 一些不知道對不對的Summary 1 想法概述 從一張充滿噪聲的圖中不斷denoise&#xff0c;最終得到一張clear的圖片。為了確定當前圖片中噪聲占比的大小&#xff0c;同時輸入…

rust踩雷筆記(1)——切片傳參和解引用賦值

最近學習rust&#xff0c;網上資料還是很有限&#xff0c;做題遇到的問題&#xff0c;有時需要自己試驗。把自己做題過程遇到的問題&#xff0c;和試驗的結論&#xff0c;做一些簡單記錄。 閱讀下列文字和代碼 用切片&#xff08;的引用&#xff09;做參數要非常小心&#xff…

LVS負載均衡之--Keepalived模式(超詳細)

一.Keepalived概述 Keepalived起初是專門針對LVS設計的一款強大的輔助工具&#xff0c;主要用來提供故障切換和健康檢查功能-----判斷LVS負載調度器&#xff0c;節點服務器的可用性&#xff0c;及時隔離并替換為新的服務器&#xff0c;當故障主機恢復后將其重新加入群集中Keep…

【數據結構】二叉樹

&#x1f407; &#x1f525;博客主頁&#xff1a; 云曦 &#x1f4cb;系列專欄&#xff1a;數據結構 &#x1f4a8;吾生也有涯&#xff0c;而知也無涯 &#x1f49b; 感謝大家&#x1f44d;點贊 &#x1f60b;關注&#x1f4dd;評論 文章目錄 前言一、樹的概念及結構&#x…

簡單理解Python中的深拷貝與淺拷貝

I. 簡介 深拷貝會遞歸的創建一個完全獨立的對象副本&#xff0c;包括所有嵌套的對象&#xff0c;而淺拷貝只復制嵌套對象的引用&#xff0c;不復制嵌套對象本身。 簡單來說就是兩者都對原對象進行了復制&#xff0c;因此使用is運算符來比較新舊對象時&#xff0c;返回的都是F…

java把數字轉換成漢字 java 數字轉漢字

使用java將數字轉化為中文漢字_java數字轉中文_javaerly的博客-CSDN博客 package com.unicom.apartment.utils;public class NumUtil {public static String convert(int number) {if(number < 0){return "";}if(number 1){return "當天";}//數字對應的…

C#實現普通的語音播報

Windows有文字轉語音功能&#xff0c;C#提供了調用的類庫Interop.SpeechLib.dll 使用方法很簡單&#xff0c;在你的項目中添加Interop.SpeechLib.dll引用&#xff0c;在類中引用&#xff1a; using SpeechLib;這里提供一個CVoice類 幫助實現語音播報 public class CVoice{pri…

【5G 核心網】5G 多PDU會話錨點技術介紹

博主未授權任何人或組織機構轉載博主任何原創文章&#xff0c;感謝各位對原創的支持&#xff01; 博主鏈接 本人就職于國際知名終端廠商&#xff0c;負責modem芯片研發。 在5G早期負責終端數據業務層、核心網相關的開發工作&#xff0c;目前牽頭6G算力網絡技術標準研究。 博客…

Spring Boot(六十四):SpringBoot集成Gzip壓縮數據

1 實現思路 2 實現 2.1 創建springboot項目 2.2 編寫一個接口,功能很簡單就是傳入一個Json對象并返回 package com.example.demo.controller;import com.example.demo.entity.Advertising; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframewo…

LeetCode150道面試經典題-- 加一(簡單)

1.題目 給定一個由 整數 組成的 非空 數組所表示的非負整數&#xff0c;在該數的基礎上加一。 最高位數字存放在數組的首位&#xff0c; 數組中每個元素只存儲單個數字。 你可以假設除了整數 0 之外&#xff0c;這個整數不會以零開頭。 2.示例 示例 1&#xff1a; 輸入&am…

excel提示更新外部引用文件 這個提示能手動禁用

是的&#xff0c;你可以手動禁用 Excel 中的更新外部引用文件的提示。這些步驟可能因 Excel 版本而有所不同&#xff0c;以下是一般的步驟&#xff1a; 1. **打開 Excel**&#xff1a; 2. **進入“選項”**&#xff1a; - 在 Excel 中&#xff0c;點擊頂部菜單中的“文件”…

網絡通信原理傳輸層TCP三次建立連接(第四十八課)

ACK :確認號 。 是期望收到對方的下一個報文段的數據的第1個字節的序號,即上次已成功接收到的數據字節序號加1。只有ACK標識為1,此字段有效。確認號X+1SEQ:序號字段。 TCP鏈接中傳輸的數據流中每個字節都編上一個序號。序號字段的值指的是本報文段所發送的數據的第一個字節的…

「UG/NX」Block UI 面收集器FaceCollector

?博客主頁何曾參靜謐的博客??文章專欄「UG/NX」BlockUI集合??全部專欄「UG/NX」NX二次開發「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序設計「C/C+&#

LangChain手記 Question Answer 問答系統

整理并翻譯自DeepLearning.AILangChain的官方課程&#xff1a;Question Answer&#xff08;源代碼可見&#xff09; 本節介紹使用LangChian構建文檔上的問答系統&#xff0c;可以實現給定一個PDF文檔&#xff0c;詢問關于文檔上出現過的某個信息點&#xff0c;LLM可以給出關于該…

【vue】項目基礎環境搭建、css樣式重置與公用

nodejs環境 nodejs是當下前端工程化開發必不可少的環境, 使用 nodejs的 npm功能來管理依賴包 查看node 和 npm的版本 node -v #查看node版本npm -v #查看npm版本 git版本控制 git版本控制工具是目前最為流行的分布式版本管理工具,代碼的**提交, 檢出, 日志**, 都需要通過git完…

Matplotlib數據可視化(二)

目錄 1.rc參數設置 1.1 lines.linestype取值 1.2 lines.marker參數的取值 1.3 繪圖中文預設 1.4 示例 1.4.1 示例1 1.4.2 示例2 1.rc參數設置 利用matplotlib繪圖時為了讓繪制出的圖形更加好看&#xff0c;需要對參數進行設置rc參數設置。可以通過以下代碼查看matplotli…