【數據結構】--二叉樹--堆(上)

一、樹的概念和結構

概念:

樹是一種非線性的數據結構,他是由n(n>=0)個有限結點組成一個具有層次關系的集合。其叫做樹,是因為他倒過來看就和一棵樹差不多,其實際上是根在上,樹枝在下的。

樹的特點:

1、其有一個特殊的結點,稱為根結點,根結點沒有前驅結點。

2、除根結點,其余的結點被分為M(M>0)個互不相交的集合,其中每個集合其又是一棵結構與樹類似的子樹,每棵子樹的根結點有且只有一個前驅,其可以有0個或者多個后繼。所以樹是遞歸定義的。

如上圖所示,樹的結構其倒過來就和我們現實生活中的樹長得很像了。

要注意的是,樹形結構中,我們的子樹之間是不能有交集的。

下面為樹的幾個要求:

1、子樹之間是不相交的(如果相交那么就是另外一種數據結構圖了)

2、除了根結點外,每個結點有且僅有一個父節點,即前驅結點有且僅有一個。

3、一顆有N個結點的樹,其邊有N-1條。

?樹的相關術語:

父結點:?若?個結點含有?結點,則這個結點稱為其?結點的?結點;如上圖:A是B的? 結點

子結點:?個結點含有的?樹的根結點稱為該結點的?結點;如上圖:B是A的孩?結點?

結點的度:?個結點有?個孩?,他的度就是多少;?如A的度為6,F的度為2,K的度為0

樹的度:一顆樹中,最大的結點的度就是這個樹的度,如上圖,結點的度最大的是A為6,那么樹的度就為6。

葉子節點:度為0的結點就為葉子結點,如上圖,B、C、H、I、J、P、Q、K、L、M、N就為葉子結點。

分支結點:度不為0的結點

結點的層次:從根的開始定義起,根為第1層、以此類推

樹的高度或深度:樹中結點的最大層次。如上圖為4?

結點的祖先:根結點。如上就是A結點

路徑:?條從樹中任意節點出發,沿?節點-?節點連接,達到任意節點的序列;?如A到Q的路徑為: A-E-J-Q;H到Q的路徑H-D-A-E-J-Q

子孫:以某結點為根的子樹中任一結點都稱為該結點的子孫。

森林:由m(m>0)棵互不相交的樹的集合稱為森林

樹的表示:

前面我們已經知道我們的樹是咋樣的情況了,那么我們在代碼中要如何進行表示一個樹結構呢?

在程序中我們表示樹的方式有很多種,我們要根據使用場景來選擇合適的表示方式,常見的表示方法有:孩子表示法,孩子兄弟表示法,雙親表示法。

下面是我們的孩子兄弟表示法:

孩子兄弟表示法,就是兩個指針,一個指針指向其左孩子,一個指針指向其右邊的第一個兄弟。

樹在實際運用:

實際上我們早已在電腦上使用過樹結構了,我們計算機上的文件存儲和管理文件的結構,其就是使用的樹形結構來組織和管理文件和文件夾的。在文件系統中,樹結構被廣泛應用,通過父結點,層層的往下找其子結點,然后找到最終的文件。其通過父結點和子結點之間的關系來表示不同的層級之間的文件和上一層文件夾之間的關系。

二、二叉樹?

二叉樹的概念和結構:

二叉樹是樹形結構中的一種特殊情況,也是我們最常用的一種樹形結構,一顆二叉樹是結點的一個有限集合,該集合由一個根結點再加上兩棵分別稱為左子樹和右子樹的二叉樹組成,或者為空。

如下:

在上面的圖中我們可以看到二叉樹的特點:

1、二叉樹不存在度大于2的結點

2、二叉樹的子樹是有左右之分的,次序是不能顛倒的,所以二叉樹是有序樹

二叉樹會有下面幾種情況:

特殊的二叉樹:

1、滿二叉樹

一個二叉樹,如果其每一層的結點樹都達到最大值,那么這個二叉樹就是滿二叉樹。即:我們現在有一個層數為k的二叉樹,那么我們的結點數,為2的k次方-1的時候,那么我們的二叉樹就是滿二叉樹。

如下:

2、完全二叉樹

完全二叉樹,也是一種特殊的二叉樹,它的定義是 在二叉樹的前提下,其除了最后一層外,其余的層的結點都是滿的,而且最后一層的結點都是集中在左側。

如下:

二叉樹的性質:

1、若規定根結點的層次為1,則一顆樹非空二叉樹的第i層上最多的結點個數為2的i次方-1個結點

2、若規定根結點 的層次為1,則一棵深度為h的二叉樹的最多的結點數為2的h次方-1個結點

3、若規定根結點的層次為1?,具有n個結點的滿二叉樹的深度h=log2(n+1)

二叉樹的存儲結構:

二叉樹一般使用兩種結構存儲嗎,一種順序結構,一種是鏈式結構。

順序存儲:

順序存儲結構底層上是使用數組來存儲,不過一般使用數組存儲的話就是滿二叉樹,因為完全二叉樹使用數組存儲,這是因為不是完全二叉樹的話,其會造成空間的浪費。

如下所示:

不過實際上我們通常將堆(二叉樹的一種)使用順序結構的數組來進行存儲,不過要注意的是這里的堆和操作系統虛擬進程地址空間中的堆是兩個回事,一個是數據結構,一個是操作系統中管理內存的一塊區域分段。

鏈式存儲:
二叉樹的鏈式存儲通過鏈表形式動態的進行表示結點間的邏輯關系,其方法如下:

通常的?法是鏈表中每個結點由三個域組成,數據域和左右指針域,左右指針分別?來給出該結點左孩?和右孩?所在的鏈結點的存儲地址。鏈式結構?分為?叉鏈和三叉鏈,當前我們學習中?般都是?叉鏈。后?課程學到?階數據結構如紅?樹等會?到三叉鏈。

其具體思路如下:

1、結點結構:

其有三個成員組成:

數據域:存儲當前結點的元素值

左指針域:指向左子結點的地址

右指針域:指向右子結點的地址

2、鏈式類型劃分:

二叉鏈:僅含左右子結點指針

? ? ? ? ? ? ? ?空間效率高,滿足基礎算法實現需求

三叉鏈:增加父結點指針域

? ? ? ? ? ? ? ?便于逆向溯源,應用于紅黑樹等復雜數據結構

三、實現順序結構二叉樹

?堆的概念和結構:

如果有?個關鍵碼的集合K? =?{k0 ,k1, k2, ...,kn?1 },把它的所有元素按完全?叉樹的順序存儲?式存儲,在?個?維數組中,并滿?:Ki<=? K(2i+1)

(K >=K(2*i+1) 且Ki<=? K (2*i+2))i = 0、1、2...,則稱為?堆(或?堆)。將根結點最?的堆叫做最?堆或?根堆,根結點最?的堆叫做最?堆或?根堆。

如下:

堆的性質:

1、堆中的某個結點的值總是不大于或者不小于其父結點

2、堆總是一棵完全二叉樹

二叉樹的一些特點:

對于具有n個結點的完全二叉樹,如果按照從上到下,從左至右的順序,對所有的結點從0開始進行編號,那么對于編號為i的結點有下面的幾個性質:

1、若i>0,i位置的父結點序號:(i-1)/2;i=0的話,那么其是根結點 ,沒有父結點

2、若2i+1<n,那么左孩子序號為2i+1,如果2i+1>=n,那么沒有左孩子

3、若2i+2<n,那么其右孩子序號為2i+2,如果2i+2>=n那么沒有右孩子

堆的實現:

前面我們已經了解了啥是堆,堆的結構是如何的,那么我們下面就通過代碼來實現堆的功能。

首先我們要創建一個堆結構,那么我們該如何進行表示呢?通過上面的學習我們知道,堆是順序存放的,那么我們堆的實現的底層還是使用數組來實現。

然后就是簡單的初始化:

那么我們的堆如何進行插入數據呢?

我們會選擇在尾部進行插入,我們插入后,如何將當前的二叉樹變成堆的結構,我們的堆是有序的,其子結點要不就是大于或者等于其父結點,要不就小于或者等于其父結點,所以我們插入尾部后,我們還需要對這個二叉樹進行調整,那么我們的堆如果是小堆,那么我們小的元素就要往上存放,父結點一定要小于子結點,所以我們可以通過當前結點找到其父結點,然后進行比較,如果新插入的結點比其父結點要小,那么新插入的結點和父結點就進行交換。如果是大堆的話,那么就還是一樣,大的往上走即可。這種方法我們叫做向上調整法。

代碼如下:

上面我們完成了入堆的操作,那么我們接下來就完成對于堆的數據的刪除,那么我們要從那里刪除呢?我們堆的刪除,就是刪除的堆頂的元素,那么我們刪除堆頂元素要如何進行刪除呢?

如果我們是直接進行刪除,那么我們就會發現,我們整個樹的結構都會發生改變,我們當前數組的元素的下標都會直接往前移動一個位置。那么我們后續再進行處理就會變得很麻煩,那么我們要如何進行處理呢?

我們可以將堆頂的元素和堆尾的元素進行交換,然后直接尾刪即可,然后我們再對堆頂的元素進行向下調整,即將這個數據和其子結點進行比較,如果是大堆的話,那么就是誰大,誰往上放,反之如果是小堆,那么誰小誰往上放。

代碼如下:

?那么上面就是我們的堆的基本功能的實現。

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

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

相關文章

linux有效裁剪視頻的方式(基于ffmpeg,不改變分辨率,幀率,視頻質量,不需要三方軟件)

就是在Linux上使用OBS Studio錄制一個講座或者其他視頻&#xff0c;可能總有些時候會多錄制一段時間&#xff0c;但是如果使用剪映或者PR這樣的工具在導出的時候總需要煩惱導出的格式和參數&#xff0c;比如剪映就不支持mkv格式的導出&#xff0c;導出成mp4格式的視頻就會變得很…

SystemVerilog—Interface語法(一)

SystemVerilog中的接口&#xff08;interface&#xff09;是一種用于封裝多模塊間通信信號和協議的復合結構&#xff0c;可顯著提升代碼復用性和維護效率。其核心語法和功能如下&#xff1a; 一、接口的基本定義 1. 聲明語法 接口通過interface關鍵字定義&#xff0c;支持信…

android binder(四)binder驅動詳解

ref&#xff1a; Android10.0 Binder通信原理(五)-Binder驅動分析_binder: 1203:1453 ioctl 40046210 77004d93f4 return-CSDN博客 https://juejin.cn/post/7214342319347712057#heading-0 第6課第1節_Binder系統_驅動情景分析_數據結構_嗶哩嗶哩_bilibili

QT/c++航空返修數據智能分析系統

簡介 1、區分普通用戶和管理員 2、界面精美 3、功能豐富 4、使用cppjieba分詞分析數據 5、支持數據導入導出 6、echarts展示圖表 效果展示 演示鏈接 源碼獲取 int main(){ //非白嫖 printf("&#x1f4e1;:%S","joyfelic"); return 0; }

ToolsSet之:數值提取及批處理

ToolsSet是微軟商店中的一款包含數十種實用工具數百種細分功能的工具集合應用&#xff0c;應用基本功能介紹可以查看以下文章&#xff1a; Windows應用ToolsSet介紹https://blog.csdn.net/BinField/article/details/145898264 ToolsSet中Number菜單下的Numeric Batch是一個數…

Ubuntu20.04 LTS 升級Ubuntu22.04LTS 依賴錯誤 系統崩潰重裝 Ubuntu22.04 LTS

服務器系統為PowerEdge R740 BIOS Version 2.10.2 DELL EMC 1、關機 開機時連續按鍵盤F2 2、System Setup選擇第一個 System BIOS 3、System BIOS Setting 選擇 Boot Setting 4、System BIOS Setting-Boot Setting 選擇 BIOS Boot Settings 5、重啟 開啟時連續按鍵盤F11 …

(javaSE)Java數組進階:數組初始化 數組訪問 數組中的jvm 空指針異常

數組的基礎 什么是數組呢? 數組指的是一種容器,可以用來存儲同種數據類型的多個值 數組的初始化 初始化&#xff1a;就是在內存中,為數組容器開辟空間,并將數據存入容器中的過程。 數組初始化的兩種方式&#xff1a;靜態初始化&#xff0c;動態初始化 數組的靜態初始化 初始化…

支持向量機(SVM)例題

對于圖中所示的線性可分的20個樣本數據&#xff0c;利用支持向量機進行預測分類&#xff0c;有三個支持向量 A ( 0 , 2 ) A\left(0, 2\right) A(0,2)、 B ( 2 , 0 ) B\left(2, 0\right) B(2,0) 和 C ( ? 1 , ? 1 ) C\left(-1, -1\right) C(?1,?1)。 求支持向量機分類器的線…

UE特效Niagara性能分析

開啟Niagara調試器 開啟顯示概覽 界面顯示 &#x1f7e9; 上方綠色面板&#xff1a;Niagara DebugHud 這是 HUD&#xff08;調試視圖&#xff09; 模式下的性能統計顯示&#xff0c;內容如下&#xff1a; 項目含義SystemFilter: ShockWave_01當前選中的 Niagara 粒子系統名稱…

碳中和新路徑:鐵電液晶屏如何破解高性能與節能矛盾?

一、顯示技術困局&#xff1a;當 “高刷” 遭遇 “高耗” 在元宇宙、電競產業蓬勃發展的當下&#xff0c;顯示設備的刷新率與能耗成為行業痛點。傳統液晶受 “邊緣場效應” 制約&#xff0c;刷新率長期停滯在 300Hz 以下&#xff0c;動態畫面拖影問題顯著&#xff1b;同時&…

Vue3+SpringBoot全棧開發:從零實現增刪改查與分頁功能

前言 在現代化Web應用開發中&#xff0c;前后端分離架構已成為主流。本文將詳細介紹如何使用Vue3作為前端框架&#xff0c;SpringBoot作為后端框架&#xff0c;實現一套完整的增刪改查(CRUD)功能&#xff0c;包含分頁查詢、條件篩選等企業級特性。 技術棧介紹 前端&#xff1…

IBM 與嘉士伯(Carlsberg)攜手推進 SAP S/4HANA 數字化轉型,打造啤酒行業新范式

在啤酒釀造擁有悠久傳統的同時&#xff0c;嘉士伯也在積極擁抱前沿技術&#xff0c;邁出數字化轉型的堅實步伐。2025年&#xff0c;嘉士伯宣布與 IBM 建立多年的合作伙伴關系&#xff0c;在其西歐業務中全面部署 SAP S/4HANA&#xff0c;旨在提升企業的運營效率、敏捷性和創新能…

深度解析 Nginx 配置:從性能優化到 HTTPS 安全實踐

引言 Nginx 作為高性能的 Web 服務器和反向代理&#xff0c;其配置靈活性和強大功能備受開發者青睞。本文基于一份生產環境的 Nginx 配置文件&#xff0c;詳細拆解其核心配置邏輯&#xff0c;涵蓋性能優化、HTTPS 安全配置、反向代理及靜態資源處理等關鍵環節&#xff0c;幫助…

傳送文件利器wormhole的使用方法

傳送文件利器wormhole的使用方法 wormhole文件傳送工具是基于python的一個快捷的傳送工具&#xff0c;在安裝此工具之前首先要部署好python環境。 安裝的過程如下&#xff1a; 1.部署好python 環境 LINUX系統自帶PYTHON環境&#xff0c;直接安裝即可。 WINDOWS系統需要安裝py…

LangChain輸出格式化實踐:提升測試工程師LLM開發效率的完整指南

引言 在基于LangChain的LLM測試開發中&#xff0c;輸出格式化是連接大模型推理能力與自動化測試系統的關鍵環節。通過結構化輸出&#xff08;如JSON&#xff09;&#xff0c;測試工程師可快速將LLM生成的測試用例、缺陷報告等結果對接至CI/CD流水線。本文系統解析LangChain內置…

Go 語言 + Word 文檔模板:WordZero 引擎如何讓企業文檔處理效率提升 300%?

前言 在企業級應用開發中&#xff0c;自動化生成Word文檔一直是個令人頭疼的需求。傳統的方案要么依賴于復雜的Office COM組件&#xff0c;要么使用功能有限的第三方庫。今天為大家介紹一個純Go語言實現的Word操作庫——WordZero&#xff0c;特別是其強大的模板引擎功能&#…

Eclipse 修改字符集

Eclipse 修改字符集 在軟件開發過程中,字符集的設置對于代碼的正確顯示和運行至關重要。Eclipse 作為一款流行的集成開發環境(IDE),提供了方便的字符集修改功能。本文將詳細講解如何在 Eclipse 中修改字符集,以確保項目文件的正確處理。 1. 引言 在 Java 開發中,常見的…

C++ 游戲開發詳細流程

&#x1f9e0; 第一階段&#xff1a;項目規劃與架構設計 關鍵詞&#xff1a;系統性、模塊化、可擴展性 1.1 目標明確 游戲類型&#xff1a;2D / 2.5D / 3D / VR平臺選擇&#xff1a;PC、主機、移動設備多人/單人&#xff1a;是否含網絡模塊&#xff08;決定是否使用 socket、U…

使用Docker-NVIDIA-GPU開發配置:解決 Docker NVIDIA 運行時錯誤方法

問題描述 運行 Docker 命令時,系統提示 docker: Error response from daemon: unknown or invalid runtime name: nvidia,表明 Docker 無法識別 NVIDIA 運行時。這一錯誤通常出現在使用 --runtime=nvidia 和 --gpus 參數時,意味著 NVIDIA 容器運行時未正確安裝或配置。NVID…

3516cv610在sample_aiisp上多創一路編碼流,方法

3516cv610在sample_aiisp上多創一路編碼流&#xff0c;方法 首先確保 vpss grp0有視頻流 最好保證 已經有一路視頻流能推出來 多創一路編碼流思路為 將 vpss grp0又綁定給 vpss_chn1 vpss_chn1有綁定給 venc_chn1 這樣我們就多創了一路視頻流。 這里思路完全正確 可以實現…