二叉樹的鏈式結構

1.二叉樹的遍歷

2.二叉樹鏈式結構的實現

3.解決單值二叉樹題

1.二叉樹的遍歷

1.1前序,中序以及后序遍歷

二叉樹的遍歷是按照某種特定的規則,依次對二叉樹的結點進行相應的操作,并且每個結點只操作一次。

二叉樹的遍歷有這些規則:前序/中序/后序/的遞歸結構遍歷

1.前序遍歷:先訪問根結點,再訪問左子樹,最后訪問右子樹

2.中序遍歷:先訪問左子樹,再訪問根結點,最后訪問右子樹

3.后序遍歷:先訪問左子樹,再訪問右子樹,最后根結點?

以前序的規則來遍歷二叉樹,進入1結點(值為1的結點),1結點為根結點所以先訪問,然后是左子樹也就是2結點,此時進入2結點后,2結點是根結點,先訪問2結點再訪問左子樹3結點,進入3結點后,以3結點作為根結點,先訪問3結點,后訪問3結點的左子樹,此時就到最后一行都是NULL結點,訪問完NULL結點后(3結點的左子樹),就訪問3結點的右子樹(NULL結點),這時候3結點已訪問完,而3結點又是2結點的左子樹,也就是說2結點的左子樹訪問完,就訪問2結點的右子樹(NULL結點),2結點也訪問完了,2結點又是1結點的左子樹,既1結點的左子樹訪問完,開始訪問1結點的右子樹,后續過程也是一樣的,每進入一個結點都是新的根結點,按照前序的遍歷,總的看就是一個遞歸過程了,只有3結點的左右子樹以及自身被訪問完后才去訪問上面結點的右子樹。

?

?

?

?訪問的順序不同也會帶來不同的特點,前序訪問則第一個是最上面的結點,中序訪問最上面的結點會把其的左右子數分成倆邊,后序則最上面的結點在最后面,中序和后序的過程與前序差不多,就是根結點的訪問有所不同。

?2.二叉樹鏈式結構的實現

2.1代碼實現遍歷二叉樹數

下面是以前序為規則遍歷的代碼實現:

#include<stdio.h>
#include<stdlib.h>
typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType data;BinaryTreeNode* left;BinaryTreeNode* right;
}BTNode;
BTNode* BuyNode(int x)
{BTNode* a = (BTNode*)malloc(sizeof(BTNode));if (a == NULL){perror("malloc fail:");return NULL;}a->data = x;a->left = NULL;a->right = NULL;return a;
}
BTNode* CreatNode()
{BTNode* node1 = BuyNode(1);BTNode* node2 = BuyNode(2);BTNode* node3 = BuyNode(3);BTNode* node4 = BuyNode(4);BTNode* node5 = BuyNode(5);BTNode* node6 = BuyNode(6);node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;return node1;
}
void PrevOver(BTNode* root)
{if (root == NULL){printf("N ");return;}printf("%d ", root->data);PrevOver(root->left);PrevOver(root->right);
}
int main()
{BTNode* root = CreatNode();PrevOver(root);return 0;
}

結果如上面分析的一樣。

只需要改變 PrevOver函數中代碼的順序就可以切換成其他的規則的遍歷,把左子樹放在根的訪問前就是中序的遍歷規則。

2.2實現計算二叉樹中的結點的個數

錯誤代碼1:

int TreeNode(BTNode* root)
{int size = 0;if (root == NULL){return 0;}++size;TreeNode(root->left);TreeNode(root->right);return size;
}

首先size是在棧區上開辟的空間,當出了這個函數,棧區就會被銷毀,函數只會傳size的值,size變量是被銷毀了,但是沒有接受返回的值,等于是去銀行取錢,結果忘記拿錢了,這樣是找不到累計的效果的,需要理解的是不是名字一樣就是同一個變量,在遞歸的過程中,雖然都是size但是這些size是在不同棧區上開辟的不同變量,只是名字相同,所以最后返回的size是第一次調用的函數的size,最后會返回1.

錯誤代碼2:

通過static可以是局部變量在出函數時不會被銷毀掉,保留size的值,使得size能達到計數的效果,

但是也有缺陷,就是在主函數中多次調用計算結點數量的函數會出問題

int TreeNode(BTNode* root)
{static int size = 0;if (root == NULL){return 0;}++size;TreeNode(root->left);TreeNode(root->right);return size;
}

多次調用計算函數:

會導致一直積累

?

錯誤代碼3:

int size = 0;
int TreeNode(BTNode* root)
{if (root == NULL){return 0;}++size;TreeNode(root->left);TreeNode(root->right);return size;
}

只需要把size從局部變量變成全局變量就行,這樣遞歸過程中的每個函數的size都是同一個size了,全局變量的生命周期是程序結束,同static一樣,但是相對static的方法安全一些,使用static需要謹慎。

合理代碼:

int TreeNode(BTNode* root)
{return root == NULL ? 0 : TreeNode(root->left) + TreeNode(root->right) + 1;
}

把根結點分成左子樹和右子樹在加1(計入一個結點數量),每次進入一個結點都會有左子樹和右子樹,每進入一個結點就計入1,直到root=NULL時返回0,就把關于根和子樹所計入的數返回到上一個結點去,通過這樣會一直返回到最上面的結點,就把所有結點的數量都計入進去了,不會出現多次調用函數而發生數量的變化。

2.3計算二叉樹的高度

因為根結點有左右倆個子樹,樹的高度是由最長的決定的,所有要對比左右倆個子樹的長度,找到長度長的子樹,再加上一(根結點算一個高度),這樣就計算出樹的高度了。

錯誤代碼:


int TreeHeight(BTNode* root)
{if (root == NULL){return 0;}return TreeHeight(root->left) > TreeHeight(root->right) ? TreeHeight(root->left)+1 : TreeHeight(root->right)+1;
}

這樣雖然可以計算出樹的高度,但是存在一個問題,函數會在樹的最下面開始計入,比我后在返回值那里又要計算一次,因為這個是沒有變量來存儲計入的值,所有每次對比和返回值時都要在通過遞歸來得到計入的值,如果樹的高度是大的,那么當遞歸到較為上面時,在往下遞歸就會導致程序運行慢,一直重復計算,計算最底下的結點的度會因為結點的上走而暴增,倒數第二層計算最后一層結點的度會執行倆次,倒數第三層則會計算最后一層結點四次,所以這個代碼是不合適的。

改進代碼:

分析:

通過遞歸會找到最下面的結點,既葉子結點,開始往上走,返回的地方就是比較那邊大,就往那邊加一(這里的一是根的計入),直到走到最上面結點,這時比較就是總的左子樹和右子樹的高度(不是最上面結點)。

int TreeHeight(BTNode* root)
{if (root == NULL){return 0;}int heightleft = TreeHeight(root->left);int heightright = TreeHeight(root->right);return heightleft > heightright ? heightleft +1 : heightright +1;
}

創建臨時變量來存儲函數返的值,就不用重復計算,可以提高運行速度,減少消耗。

2.4計算樹的葉子結點個數

葉子結點的左右子數都是NULL,可以以此為特點找。

錯誤代碼:

int LeafNode(BTNode* root)
{if (root->left == NULL && root->right == NULL)return 1;return LeafNode(root->left) + LeafNode(root->right);
}

因為二叉樹不是所有結點都有左右子樹,有些子樹是NULL,如果為NULL則是不能用->符號引用的,所以代碼是不合理的。

改進代碼:

int LeafNode(BTNode* root)
{if (root == NULL)return 0;if (root->left == NULL && root->right == NULL)return 1;return LeafNode(root->left) + LeafNode(root->right);
}

先在最前面判斷是否為空,在進行下面的操作,就可以避免遇到NULL而去解引。

3.解決單值二叉樹題

?題意可以知道單值二叉樹是結點的值是一樣的,需要去遍歷二叉樹去判斷是否所有的值都相等,

通過判斷根和左右子樹是否相等,如果每個根和左右子樹都相等,則整體的全部值也會相等,就像a=b,b=c,所以a=b=c。

代碼:

bool isUnivalTree(struct TreeNode* root) {if(root==NULL)return true;if(root->left&&root->left->val!=root->val)return false;if(root->right&&root->right->val!=root->val)return false;return isUnivalTree(root->left)&&isUnivalTree(root->right);}

分析:

之所用如果不相等就返回false是因為后面的子結點是否相等還不知道,判斷相等就返回true太早了,可能后面的值與前面的不相等,只有全部相等才能返回true。?

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

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

相關文章

主流電商平臺商品實時數據采集API接口||抖音電商數據分析實例|可視化

— 1 — 抖音電商數據【抖音電商API數據采集】分析場景 1. 這里&#xff0c;我們選擇“伊利”這個品牌作為案例進行分析&#xff0c;在短短的4個月里&#xff0c;從最初每月營收17.07萬&#xff0c;到6月份達到了2485.54 萬&#xff0c;伊利的牛奶&#xff0c;有點牛&#xff…

Spring 對 Junit4,Junit5 的支持上的運用

1. Spring 對 Junit4,Junit5 的支持上的運用 文章目錄 1. Spring 對 Junit4,Junit5 的支持上的運用每博一文案2. Spring對Junit4 的支持3. Spring對Junit5的支持4. 總結&#xff1a;5. 最后&#xff1a; 每博一文案 關于理想主義&#xff0c;在知乎上看到一句話&#xff1a;“…

在Windows下訪問WSL(Windows Subsystem for Linux)文件夾

在Windows下訪問WSL&#xff08;Windows Subsystem for Linux&#xff09;文件夾&#xff0c;可以按照以下步驟操作&#xff1a; 通過Windows文件資源管理器訪問&#xff1a; 打開文件資源管理器。在地址欄中輸入\\wsl$&#xff0c;然后按回車鍵。這將打開一個顯示WSL可用發行版…

kafka配置消費者重要參數

文章目錄 fetch.min.bytesfetch.max.wait.msfetch.max.bytesmax.poll.recordsmax.partition.fetch.bytessession.timeout.ms和heartbeat.interval.msmax.poll.interval.msrequest.timeout.msauto.offset.resetenable.auto.commitpartition.assignment.strategy區間(range)輪詢(…

Xline社區會議Call Up|在 CURP 算法中實現聯合共識的安全性

為了更全面地向大家介紹Xline的進展&#xff0c;同時促進Xline社區的發展&#xff0c;我們將于2024年5月31日北京時間11:00 p.m.召開Xline社區會議。 歡迎您屆時登陸zoom觀看直播&#xff0c;或點擊“閱讀原文”鏈接加入會議&#xff1a; 會議號: 832 1086 6737 密碼: 41125…

通過cmd命令行使用用3dmax自帶的vray渲染

有時調試需要使用vray渲染vrscene文件看效果&#xff0c;只裝有3dmax下可以使用自帶vray渲染&#xff0c;在3dmax的渲染日志里面看自帶引擎路徑 使用命令行進入到此目錄 執行命令指定vr文件即可看到效果&#xff0c;如&#xff1a;vray.exe -sceneFile“C:\test15\202405241…

pip安裝報錯解決之后,手動安裝太麻煩,怎么辦

在使用pip install package_name安裝公共庫的時候,經常會報錯: Microsoft Windows [版本 6.1.7601] 版權所有 (c) 2009 Microsoft Corporation。保留所有權利。C:\Users\Administrator>pip install hatch WARNING: Ignoring invalid distribution -ip (d:\soft\python\py…

記一次成功的性能調優

環境&#xff1a;mysql8&#xff0c;表A大小10G&#xff0c;dbeaver24.0.5 現象&#xff1a;查詢頁面加載數據慢 操作&#xff1a; 第一步&#xff1a;新建sql編輯器&#xff0c;把sql貼到編輯器&#xff0c;帶參數&#xff1b; 第二步&#xff1a;在sql前加explain空一個并…

Cesium與Three相機同步(2)

之前實現了將Three相機同步到Cesium相機Cesium與Three相機同步(1)-CSDN博客 現在是將Cesium相機同步到Three相機,從而實現了相機雙向同步。 <!DOCTYPE html> <html lang="en"><head><title>three.js webgl - orbit controls</title&g…

【教學類-58-03】黑白三角拼圖03(4*4宮格)總數算不出+隨機抽取10張

背景需求&#xff1a; 【教學類-58-01】黑白三角拼圖01&#xff08;2*2宮格&#xff09;256種-CSDN博客文章瀏覽閱讀318次&#xff0c;點贊10次&#xff0c;收藏12次。【教學類-58-01】黑白三角拼圖01&#xff08;2*2宮格&#xff09;256種https://blog.csdn.net/reasonsummer/…

【Jmeter】使用Jmeter進行接口測試、跨線程組獲取參數

Jmeter接口測試 Jmeter設置成中文實操練習-跨線程組提取參數&#xff0c;使用值HTTP請求默認值&HTTP信息頭管理器 相信打算從事測試工程師的同學們&#xff0c;肯定對Jmeter是耳熟能詳的。使用Jmeter可以進行接口測試、性能測試、壓力測試等等&#xff1b;這個章節介紹如何…

Cisco Catalyst 9000 9200 9300 9400 IOS software upgrade

1 背景 從Catalyst 3650 ,3850&#xff0c;Catalyst 9000開始, 更準確的說是IOS XE的交換機的系統鏡像安裝方式分為2種 ? Bundle mode ? Install mode 這2種方工啥區別&#xff1f; Bundle mode 傳統方式利用boot system flash:c9k.xx16.bin方式引導 Install mode 將bin文…

用友 存貨分類按層級取數SQL語句

SELECT cInvCCode 分類編碼, cInvCName 分類名稱, iInvCGrade 分類層級, ss.bInvCEnd 是否是末級, aa.* FROM InventoryClass ss LEFT JOIN ( SELECT * FROM ( SELECT cInvCCode AS 一級分類編碼, …

cocos 通過 electron 打包成 exe 文件,實現通信問題

cocos 通過 electron 打包成 exe 文件&#xff0c;實現通信問題 首先&#xff0c;我使用的 cocos 版本是 2.4.12&#xff0c;遇到一個問題&#xff0c;是啥子呢&#xff0c;就是我要把用 cocos 開發出來的項目打包成一個 exe 可執行程序&#xff0c;使用的是 electron &#xf…

【C++算法】BFS解決多源最短路問題相關經典算法題

1.01矩陣 既然本章是BFS解決多源最短路問題&#xff0c;也就是說有若干個起點&#xff0c;那我們就可以暴力一點&#xff0c;直接把多源最短路徑問題轉化成若干個單源最短路徑問題&#xff0c;然后將每次的步數比較一下&#xff0c;取到最短的就是最短路徑的結果&#xff0c;這…

arcgis 10.6 工具欄操作error 001143 后臺服務器拋出異常

arcgis 10.6 工具欄操作error 001143 后臺服務器拋出異常 環境 win10arcgis 10.6 問題 執行定義投影要素轉線出現 Error: 001143:后臺服務器拋出異常&#xff08;差點重裝10.6&#xff09; 如下圖所示&#xff1a; 解決方法 通過在菜單工具條上單擊地理處理 > 地理處…

設計模式使用(成本扣除)

前言 名詞解釋 基礎名詞 訂單金額&#xff1a;用戶下單時支付的金額&#xff0c;這個最好理解 產品分成&#xff1a;也就是跟其他人合做以后我方能分到的金額&#xff0c;舉個例子&#xff0c;比如用戶訂單金額是 100 塊&#xff0c;我方的分成是 80%&#xff0c;那么也就是…

OceanMind海睿思通過上海數交所數商認證,提供高質量數據治理和數據咨詢服務

近日&#xff0c;中新賽克海睿思成功通過上海數據交易所的數商認證&#xff0c;獲得上海數據交易所頒發的“數據產品開發服務商”、“數據治理服務商”和“數據咨詢服務商”三大證書。 作為由深圳市創新投資集團有限公司投資控股的高新技術企業&#xff0c;國家級專精特新“小巨…

如何通過OpenHarmony的音頻模塊實現錄音變速功能?

簡介 OpenAtom OpenHarmony&#xff08;以下簡稱“OpenHarmony”&#xff09;是由開放原子開源基金會孵化及運營的開源項目&#xff0c;是面向全場景、全連接、全智能時代的智能物聯網操作系統。 多媒體子系統是OpenHarmony系統中的核心子系統&#xff0c;為系統提供了相機、…

2024-05-24 問AI: 在深度學習中,什么是L1 正則化和L2 正則化?

文心一言 在深度學習和機器學習中&#xff0c;正則化是一種用于防止模型過擬合的技術。它通過向損失函數添加一個懲罰項來實現&#xff0c;這個懲罰項與模型的復雜度有關。正則化項可以看作是對模型參數的約束&#xff0c;使得模型在訓練時不僅關注于最小化訓練誤差&#xff0…