二叉樹-堆的詳解

一,樹的概念

1,樹的概念

樹是一種非線性的數據結構,它是由n(n>=0)個有限結點組成一個具有層次關系的集合。

把它叫做樹是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。

有一個特殊的結點,稱為根結點,根結點沒有前驅結點

除根結點外,其余結點被分成M(M>0)個互不相交的集合

T1、T2、……、Tm,其中每一個集合Ti(1<= i <= m)又是一棵結構與樹類似的子樹。每棵子樹的根結點有且只有一個前驅,可以有0個或多個后繼

因此,樹是遞歸定義的

注意:樹形結構中,子樹之間不能有交集,否則就不是樹形結構

2,樹的相關概念

3,二叉樹的概念

一棵二叉樹是結點的一個有限集合,該集合:

1. 或者為空

2. 由一個根結點加上兩棵別稱為左子樹和右子樹的二叉樹組成

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

2. 二叉樹的子樹有左右之分,次序不能顛倒,因此二叉樹是有序樹

注意:對于任意的二叉樹都是由以下幾種情況復合而成的:?

特殊的二叉樹:

1. 滿二叉樹:一個二叉樹,如果每一個層的結點數都達到最大值,則這個二叉樹就是滿二叉樹。也就是 說,如果一個二叉樹的層數為K,且結點總數是 ,則它就是滿二叉樹。

2. 完全二叉樹:完全二叉樹是效率很高的數據結構,完全二叉樹是由滿二叉樹而引出來的。對于深度為K 的,有n個結點的二叉樹,當且僅當其每一個結點都與深度為K的滿二叉樹中編號從1至n的結點一一對 應時稱之為完全二叉樹。 要注意的是滿二叉樹是一種特殊的完全二叉樹。

?

?節點與高度關系

設高度為h,節點個數為N??

?

4,堆的概念

如果有一個關鍵碼的集合K = { , , ,…, },把它的所有元素按完全二叉樹的順序存儲方式存儲 在一個一維數組中,并滿足: = 且 >= ) i = 0,1, 2…,則稱為小堆(或大堆)。將根結點最大的堆叫做最大堆或大根堆,根結點最小的堆叫做最小堆或小根堆。 ?

物理:數組

邏輯:完全二叉樹

堆的性質

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

堆總是一棵完全二叉樹。

二,堆的實現

老規矩建立三個文件 Heap.c Heap.h Test.c

?1,堆的結構

typedef int HPDataType;typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;

2,堆的初始化

void HPInit(HP* php);

void HPInit(HP* php)
{assert(php);php->a = NULL;php->capacity = php->size = 0;
}

3,堆的銷毀

void HPDestroy(HP* php);

void HPDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->size = php->capacity = 0;
}

4,數據的交換

?void Swap(HPDataType* p1, HPDataType* p2);

void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}

5,向上調整(小堆為例)

void AdjustUp(HPDataType* a, int child);

void AdjustUp(HPDataType* a, int child)
{// 初始條件// 中間過程// 結束條件int parent = (child - 1) / 2;//while (parent >= 0)while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}

條件while (parent >= 0) 不準確,由于child==0時,parent = (child - 1) / 2;是整型還是為0,故可以實現?

6,堆的插入

void HPPush(HP* php, HPDataType x);

判斷空間是否足夠

if (php->size == php->capacity){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, newcapacity * sizeof(HPDataType));if (tmp == NULL){perror("realloc fail");return;}

插入數據

php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;

調整數據

AdjustUp(php->a, php->size - 1);

總代碼

void HPPush(HP* php, HPDataType x)
{assert(php);if (php->size == php->capacity){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, newcapacity * sizeof(HPDataType));if (tmp == NULL){perror("realloc fail");return;}php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);
}

?

?

?

??

7,堆的刪除(刪除堆頂)

挪動覆蓋刪除堆頂數據,會導致堆的關系錯誤

可以將堆頂數據和堆尾數據互換,這樣其兩個左右子樹還是小堆,然后使用向下調節算法?

?

void HPPop(HP* php);

void HPPop(HP* php)
{assert(php);assert(php->size > 0);Swap(&php->a[0], &php->a[php->size-1]);php->size--;AdjustDown(php->a, php->size, 0);
}

8,向下調整(小堆為例)?

?void AdjustDown(HPDataType* a, int n, int parent);

void AdjustDown(HPDataType* a, int n, int parent)
{// 先假設左孩子小int child = parent * 2 + 1;while (child < n)  // child >= n說明孩子不存在,調整到葉子了{// 找出小的那個孩子if (child + 1 < n && a[child + 1] < a[child]){++child;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

?9,取堆頂數據

HPDataType HPTop(HP* php);

HPDataType HPTop(HP* php)
{assert(php);assert(php->size > 0);return php->a[0];
}

10,判斷堆是否為空

bool HPEmpty(HP* php);

bool HPEmpty(HP* php)
{assert(php);return php->size == 0;
}

?三,堆的應用

利用堆排序

向上調整建堆

for (int i = 1; i < n; i++){AdjustUp(a, i);}

?向下調整建堆

for (int i = (n-1-1)/2; i >= 0; i--){AdjustDown(a, n, i);}

完整代碼

void HeapSort(int* a, int n)
{// 降序,建小堆// 升序,建大堆/*for (int i = 1; i < n; i++){AdjustUp(a, i);}*/for (int i = (n-1-1)/2; i >= 0; i--){AdjustDown(a, n, i);}int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;}
}

?

不可以用大堆進行降序,因為首先第一個定死了,后面接著用大堆會使關系錯亂

建堆時間復雜度?

向下調整

因為堆是完全二叉樹,而滿二叉樹也是完全二叉樹,此處為了簡化使用滿二叉樹來證明(時間復雜度本來看的 就是近似值,多幾個結點不影響最終結果):

?

向下調整建堆 O(N)?

向上調整

?

向上調整建堆O(N*logN)

n個數找最大的前K個

方法一

建一個N個數的大堆? O(N)

pop k次 O(K*logN)

方法二

用前k個數 建一個小堆 O(K)

剩下的數跟堆頂數據比較,如果比堆頂數據大,就替代堆頂數據進堆(覆蓋跟位置然后向下調整)

O(log K*(N-K))

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

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

相關文章

vue3 + echarts 二次開發百分比餅圖

效果圖&#xff1a; 安裝 pnpm i echarts 公共模塊組件 <divclass"pie"ref"percent"style"width: 100%; height: calc(100% - 48px)"></div> import { ref, onMounted } from vue import * as echarts from echarts const prop…

【JavaScript腳本宇宙】解密前端工具:選擇最佳JavaScript模塊管理工具

精選前端工具匯總&#xff1a;打包器和捆綁器的完整指南 前言 在現代Web開發中&#xff0c;使用適當的工具和庫可以極大地提高開發效率和項目質量。本文將介紹一些常用的Web應用程序捆綁器&#xff0c;這些工具能夠幫助開發人員有效地管理JavaScript模塊和資源。 歡迎訂閱專欄…

SpringBoot項目啟動提示端口號占用

Windows環境下&#xff0c;SpringBoot項目啟動時報端口號占用&#xff1a; *************************** APPLICATION FAILED TO START ***************************Description:Web server failed to start. Port 8080 was already in use.Action:Identify and stop the proc…

【樂吾樂3D可視化組態編輯器】狀態告警示例

狀態告警的設置方法為兩種&#xff1a; 1.通過數據點號設置&#xff08;推薦&#xff09;&#xff1a; 適用于綁定單一數據點號&#xff0c;設置邏輯簡潔&#xff0c;實現簡單邏輯交互 2.通過交互事件監聽數據點號設置&#xff1a; 適用于綁定多個數據點號&#xff0c;實現復…

LLM大模型AI應用的三階技術

第一階 指令工程&#xff08;Prompt Enginner&#xff09; 設計提示&#xff08;Prompt Design&#xff09; 結果優化&#xff08;Response Optimization&#xff09; 交互設計&#xff08;Interaction Design&#xff09; 模型理解&#xff08;Model Understanding&#…

哈希經典題目(C++)

文章目錄 前言一、兩數之和1.題目解析2.算法原理3.代碼編寫 二、判定是否互為字符重排1.題目解析2.算法原理3.代碼編寫 三、 字?異位詞分組1.題目解析2.算法原理3.代碼編寫 總結 前言 哈希表是一個存儲數據的容器&#xff0c;我們如果想要快速查找某個元素&#xff0c;就可以…

Python驅動下的AI革命:技術賦能與案例解析

在當今這個信息化、數據化的時代&#xff0c;人工智能&#xff08;AI&#xff09;已經成為推動社會發展的重要力量。而Python&#xff0c;作為一種簡單易學、功能強大的編程語言&#xff0c;在AI領域的應用中發揮著至關重要的作用。本文將探討Python在AI領域的應用、其背后的技…

MMUNet:形態學特征增強網絡在結腸癌病理圖像分割中的應用

MMUNet: Morphological feature enhancement network for colon cancer segmentation in pathological images. 發表在&#xff1a;Biomedical Signal Processing and Control2024--影響因子&#xff1a;3.137 南華大學的論文 論文地址&#xff1a;main.pdf (sciencedirecta…

Wakeup Source框架設計與實現

Wakeup Source 為系統組件提供了投票機制&#xff0c;以便低功耗子系統判斷當前是否可以進入休眠。 Wakeup Source(后簡稱&#xff1a;WS) 模塊可與內核中的其他模塊或者上層服務交互&#xff0c;并最終體現在對睡眠鎖的控制上。 1. 模塊功能說明 WS的處理邏輯基本上是圍繞 com…

后端進階-分庫分表

文章目錄 為什么需要分庫為什么需要分表 什么時候需要分庫分表只需要分庫只需要分表 分庫分表解決方案垂直分庫水平分庫垂直分表水平分表 分庫分表常用算法范圍算法hash分片查表分片 分庫分表模式客戶端模式代理模式 今天跟著訓練營學習了分庫分表&#xff0c;整理了學習筆記。…

機器學習模型進行預測和回測

這段代碼是為了并行地處理多個 CSV 文件&#xff0c;并使用機器學習模型進行預測和回測。主要涉及以下步驟&#xff1a; 初始化環境與設置&#xff1a; 引入必要的庫&#xff0c;如 ray 用于并行計算&#xff0c;pandas 用于數據處理&#xff0c;tqdm 用于進度條顯示等。設置一…

golang 不用sleep如何實現實現每隔指定時間執行一次for循環?

今天介紹的是在go語言里面不用time.Sleep&#xff0c; 使用for range 定時器管道 來實現按照我們指定的時間間隔來執行for循環, 即&#xff1a; for range ticker.C { } 這樣就實現了for每隔指定時間執行一次&#xff0c;除非管道被關閉&#xff0c;否則for而且會一直柱塞當前線…

淺說線性DP(下)

聲明 最近博主身體不適&#xff0c;更新較慢&#xff0c;請大家體諒體諒 最大上升子序列 【題目描述】 一個數的序列 你的任務&#xff0c;就是對于給定的序列&#xff0c;求出最大上升子序列和。注意&#xff0c;最長的上升子序列的和不一定是最大的&#xff0c;比如序列(1…

03-3.3.1 棧在括號匹配中的應用

&#x1f44b; Hi, I’m Beast Cheng&#x1f440; I’m interested in photography, hiking, landscape…&#x1f331; I’m currently learning python, javascript, kotlin…&#x1f4eb; How to reach me --> 458290771qq.com 喜歡《數據結構》部分筆記的小伙伴可以訂…

echarts的使用

一 echarts的使用 引入 echarts.js 文件 <script src"https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script> 準備一個呈現圖表的盒子 <div class"container"><div class"t_header"><span>端午…

東方博宜1760 - 整理抽屜

題目描述 期末考試即將來臨&#xff0c;小T由于同時肩負了學習、競賽、班團活動等多方面的任務&#xff0c;一直沒有時間好好整理他的課桌抽屜&#xff0c;為了更好地復習&#xff0c;小T首先要把課桌抽屜里的書分類整理好。 小T的抽屜里堆著 N 本書&#xff0c;每本書的封面上…

智能視頻監控平臺LntonCVS視頻融合共享平臺保障露營安全解決方案

在當今社會&#xff0c;都市生活的快節奏和壓力使得越來越多的人渴望逃離城市的喧囂&#xff0c;尋求一種短暫的慢生活體驗。他們向往在壯麗的山河之間或寧靜的鄉村中露營&#xff0c;享受大自然的寧靜與美好。隨著露營活動的普及&#xff0c;露營地的場景也變得更加豐富多樣&a…

使用python繪制核密度估計圖

使用python繪制核密度估計圖 核密度估計圖介紹效果代碼 核密度估計圖介紹 核密度估計&#xff08;Kernel Density Estimation&#xff0c;KDE&#xff09;是一種用于估計數據概率密度函數的非參數方法。與直方圖不同&#xff0c;KDE 可以生成平滑的密度曲線&#xff0c;更好地…

Mybatis使用緩存的配置總結

1.全局變量配置cacheEnabled&#xff1a; ture&#xff08;默認&#xff09;&#xff1a;開啟二級緩存&#xff0c; false&#xff1a;關閉二級緩存&#xff0c;但一級緩存不受影響 2.映射文件中mapper標簽下&#xff1a; 配置有&#xff1a;開啟二級緩存 沒配置有&#x…

LeetCode62不同路徑

題目描述 一個機器人位于一個 m x n 網格的左上角 &#xff08;起始點在下圖中標記為 “Start” &#xff09;。機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角&#xff08;在下圖中標記為 “Finish” &#xff09;。問總共有多少條不同的路徑&#xff1f; …