【數據結構與算法篇】二叉樹鏈式結構及實現

【數據結構與算法篇】二叉樹鏈式結構及實現

🥕個人主頁:開敲🍉

🔥所屬專欄:每日刷題🍍

🌼文章目錄🌼

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

? ? 4.1 前置說明

? ? 4.2 二叉樹的遍歷

? ? ? ??4.2.1 前序、中序以及后序遍歷

? ? ? ? 4.2.2 層序遍歷

? ? 4.3 結點個數及高度等

? ? 4.4 二叉樹基礎OJ聯系

? ? 4.5 二叉樹的創建和銷毀

4. 二叉樹鏈式結構的實現
? ? 4.1 前置說明

??在學習二叉樹的基本操作前,需先要創建一棵二叉樹,然后才能學習其相關的基本操作。由于現在大家對二叉樹結構掌握還不夠深入,為了降低大家學習成本,此處手動快速創建一棵簡單的二叉樹,快速進入二叉樹操作學習,等二叉樹結構了解的差不多時,我們反過頭再來研究二叉樹真正的創建方式。

typedef int BTDataType;
typedef struct BinaryTreeNode
{
? ? ? BTDataType _data;
? ? ? struct BinaryTreeNode* _left;
? ? ? struct BinaryTreeNode* _right;
? ? ? }BTNode;


BTNode* CreatBinaryTree()
{
? ? 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;
}

注意:上述代碼并不是創建二叉樹的方式,真正創建二叉樹方式后序詳解重點講解。
再看二叉樹基本操作前,再回顧下二叉樹的概念,二叉樹是:

從概念中可以看出,二叉樹定義是遞歸式的,因此后序基本操作中基本都是按照該概念實現的。

? ? 4.2 二叉樹的遍歷
? ? ? ??4.2.1 前序、中序以及后序遍歷

??學習二叉樹結構,最簡單的方式就是遍歷。所謂二叉樹遍歷(Traversal)是按照某種特定的規則,依次對二叉樹中的結點進行相應的操作,并且每個結點只操作一次。訪問結點所做的操作依賴于具體的應用問題。 遍歷是二叉樹上最重要的運算之一,也是二叉樹上進行其它運算的基礎。

??按照規則,二叉樹的遍歷有:前序/中序/后序的遞歸結構遍歷:

? ① 前序:對于每個結點,都滿足 根 一> 左子樹 一> 右子樹 的遍歷順序

??② 中序:對于每個結點,都滿足 左子樹 一> 根 一> 右子樹 的遍歷順序

??③ 后序:對于每個結點,都滿足 左子樹 一> 右子樹 一> 根 的遍歷順序

??由于被訪問的結點必是某子樹的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解釋為根、根的左子樹和根的右子樹。NLR、LNR和LRN分別又稱為先根遍歷、中根遍歷和后根遍歷。

? 前序遍歷圖形解釋:

類似的可以推出中序遍歷:

以及后序遍歷:

? ? ? ? 4.2.2 層序遍歷

??層序遍歷:除了先序遍歷、中序遍歷、后序遍歷外,還可以對二叉樹進行層序遍歷。設二叉樹的根結點所在層數為1,層序遍歷就是從所在二叉樹的根結點出發,首先訪問第一層的樹根結點,然后從左到右訪問第2層上的結點,接著是第三層的結點,以此類推,自上而下,自左至右逐層訪問樹的結點的過程就是層序遍歷。

??

? ? 4.3 結點個數及高度等

//二叉樹結點個數

//求二叉樹結點個數,也就是將每個根節點左右子樹結點個數相加,再加上根結點自身。
int TreeNodeSize(BT* node)
{
?? ?if (node == NULL)
?? ?{
?? ??? ?return 0;
?? ?}
?? ?return 1 + TreeNodeSize(node->left) + TreeNodeSize(node->right);
}

//二叉樹葉結點個數
int TreeLeafSize(BT* node)
{
?? ?if (node == NULL)
?? ?{
?? ??? ?return 0;
?? ?}
?? ?if (node->left == NULL && node->right == NULL)
?? ?{
?? ??? ?return 1;
?? ?}
?? ?return TreeLeafSize(node->left) + TreeLeafSize(node->right);
}

//二叉樹第K層結點個數
int TreeKSize(BT* node,int k)
{
?? ?if (node == NULL)
?? ?{
?? ??? ?return 0;
?? ?}
?? ?else if (k == 0)
?? ?{
?? ??? ?return 1;
?? ?}
?? ?return TreeKSize(node->left,k-1) + TreeKSize(node->right,k-1);
}

//查找值為x的結點
BT* FindX(BT* node, BTDataType x)
{
?? ?if (node == NULL)
?? ?{
?? ??? ?return NULL;
?? ?}
?? ?if (node->val == x)
?? ?{
?? ??? ?return node;
?? ?}
?? ?BT* ansleft = FindX(node->left, x);
?? ?if (ansleft)
?? ?{
?? ??? ?return ansleft;
?? ?}
?? ?return FindX(node->right,x);
}

? ? 4.4 二叉樹基礎OJ聯系

? ?965. 單值二叉樹 - 力扣(LeetCode)

? ?100. 相同的樹 - 力扣(LeetCode)

? 101. 對稱二叉樹 - 力扣(LeetCode)

? ?144. 二叉樹的前序遍歷 - 力扣(LeetCode)

? ?94. 二叉樹的中序遍歷 - 力扣(LeetCode)

? ?145. 二叉樹的后序遍歷 - 力扣(LeetCode)

? 572. 另一棵樹的子樹 - 力扣(LeetCode)

? ? 4.5 二叉樹的創建和銷毀

??二叉樹遍歷_牛客題霸_牛客網 (nowcoder.com)

??//前序遍歷創建二叉樹
BT* BinaryTreeCreate(BTDataType* a, int* n)
{
?? ?if (a[*n] == 0)
?? ?{
?? ??? ?(*n)++;
?? ??? ?return NULL;
?? ?}
?? ?BT* node = (BT*)malloc(sizeof(BT));
?? ?node->val = a[(*n)++];
?? ?node->left = BinaryTreeCreate(a, n);
?? ?node->right = BinaryTreeCreate(a, n);
?? ?return node;
}

//二叉樹銷毀(后序遍歷)
void ReleaseBinaryTree(BT* node)
{
?? ?if (node == NULL)
?? ?{
?? ??? ?return;
?? ?}
?? ?ReleaseBinaryTree(node->left);
?? ?ReleaseBinaryTree(node->right);
?? ?free(node);
}

//判斷二叉樹是否是完全二叉樹
bool IsFullBinaryTree(BT* node)
{
?? ??? ?QE q;
?? ?//初始化隊列
?? ?QueInit(&q);
?? ?//入列,隊列中的val存放指向結點的指針
?? ?if (node)
?? ??? ?QuePush(&q, node);

?? ?while (!QueEmpty(&q))
?? ?{
?? ??? ?QDataType phead = QueGetHead(&q);
?? ??? ?QuePop(&q);
?? ??? ?if (phead == NULL)
?? ??? ?{
?? ??? ??? ?break;
?? ??? ?}

?? ??? ?QuePush(&q, phead->left);
?? ??? ?QuePush(&q, phead->right);
?? ?}
?? ?while (!QueEmpty(&q))
?? ?{
?? ??? ?QDataType phead = QueGetHead(&q);
?? ??? ?if (phead)
?? ??? ?{
?? ??? ??? ?QueRelease(&q);
?? ??? ??? ?return false;
?? ??? ?}
?? ??? ?QuePop(&q);
?? ?}
?? ?QueRelease(&q);
?? ?return true;
}

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

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

相關文章

通過ssh在本地打開遠程服務器的網頁

用途 在遠程服務器使用jupyter notebook或者tensorboard等時,在本地打開服務器端的網頁的方式有很多比如可以使用MobaXterm工具等,此方法可參考https://blog.csdn.net/cc__cc__/article/details/108060618?spm1001.2014.3001.5502。 若直接使用ssh則可…

C++感受11-Hello Object 成員版

當一個C程序員在設計類型時,他在想什么? 這一類型的對象,需要擁有哪些屬性數據?這一類型的對象,它將擁有哪些功能?這一類型的對象,它的各個屬性和功能之間,有哪些關聯關系&#xff1…

OceanBase的存儲架構與傳統LSM-Tree架構的異同|OceanBase數據轉儲合并技術解讀(二)

前篇博文將OceanBase的存儲架構巧妙地與自然界中的“水生態”進行了類比,今日我們轉變視角,聚焦在與擁有相同LSM-Tree架構的其他產品的比較,深入探討OceanBase相較于它們所展現出的獨特性能。 眾所周知,OceanBase數據庫的存儲引擎…

element-ui 前端ui框架用法開發指南(2024-05-22)

Element,一套為開發者、設計師和產品經理準備的基于 Vue 2.0 的桌面端組件庫 1、npm安裝 // npm安裝:npm install element-ui --save 能更好地和 webpack 打包工具配合使用 2、cdn在線引入 訪問最新版本的資源地址 - element-uiThe CDN for element-u…

RedHat9 | DNS剖析-配置主DNS服務器實例

一、實驗環境 1、BIND軟件包介紹 BIND軟件是一款開放源碼的DNS服務器軟件,由美國加州大學Berkeley分校開發和維護,全稱為Berkeley Internet Name Domain。該軟件在DNS(域名系統)領域具有重要地位,是目前世界上使用最…

使用OpenCV dnn c++加載YOLOv8生成的onnx文件進行目標檢測

在網上下載了60多幅包含西瓜和冬瓜的圖像組成melon數據集,使用 LabelMe 工具進行標注,然后使用 labelme2yolov8 腳本將json文件轉換成YOLOv8支持的.txt文件,并自動生成YOLOv8支持的目錄結構,包括melon.yaml文件,其內容…

信息系統管理工程師問答題

信息系統管理工程師問答題 系統管理安全兩方面 安全測試 入侵檢測系統的功能 用戶標識與驗證常用的3種方法 (1) 要求用戶輸入一些保密信息,例如用戶名稱和密碼; (2) 采用物理識別設備,例如訪問卡、鑰匙或令牌; (3) 采用生物統計學…

Python怎樣定位并刪除Sql語句中不確定的查詢條件

1.問題場景描述: 在sql語句中經常會有查詢條件是:查找多個訂單簽訂日期范圍的數據,但具體的日期范圍是不確定,我們如何來查找定位 例如:查詢條件語句的部分如下圖: 目標是: 1)定位字符串:t_contract_order.sign_date 2)最終得到結果: 解決問題思路: 1)定位要找的字符串起始位置…

【學習心得】PyTorch的知識要點復習(持續更新)

PyTorch知識要點復習,目的是為了鞏固PyTorch基礎、快速回顧、深化理解PyTorch框架。這篇文章會持續更新。 一、本文的一些說明 知識點梳理:我將PyTorch的核心概念和高級技巧進行了系統化的整理,從基礎的張量操作到復雜的模型構建與訓練。這樣…

【Linux】進程終止與進程等待

目錄 進程終止 errno exit和_exit 進程等待 wait和waitpid 宏:WIFEXITED 非阻塞等待 進程終止 下面要談的一個話題就是進程終止,就是說一個進程退出了,可能有三種情況 1.進程代碼執行完,結果是正確的 2.進程代碼執行完&…

【九十二】【算法分析與設計】875. 愛吃香蕉的珂珂,410. 分割數組的最大值,機器人跳躍問題,二分答案法

875. 愛吃香蕉的珂珂 - 力扣(LeetCode) 珂珂喜歡吃香蕉。這里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警衛已經離開了,將在 h 小時后回來。 珂珂可以決定她吃香蕉的速度 k (單位:根/小時)。每…

【活動】開源與閉源大模型:探索未來趨勢的雙軌道路

🌈個人主頁: 鑫寶Code 🔥熱門專欄: 閑話雜談| 炫酷HTML | JavaScript基礎 ?💫個人格言: "如無必要,勿增實體" 文章目錄 開源與閉源大模型:探索未來趨勢的雙軌道路引言一、開源大模型&#…

翻譯《The Old New Thing》- The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag

The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20071128-00/?p24353 Raymond Chen 2007年11月28日 FORMAT_MESSAGE_IGNORE_INSERTS 標志的重要性 簡要 文章討論了使用FormatMes…

評估企業的業務是否存在高風險的六個步驟

風險的幽靈使得組織別無選擇,只能改善各種網絡風險的總體管理。以下是一個基于信息安全論壇的IRAM2方法論的分步過程,網絡安全和風險從業者可以利用它來評估和管理信息風險。 第1步:范圍界定練習 范圍界定練習的目標是提供一個以業務為中心…

基于springboot+vue的招聘信息管理系統

開發語言:Java框架:springbootJDK版本:JDK1.8服務器:tomcat7數據庫:mysql 5.7(一定要5.7版本)數據庫工具:Navicat11開發軟件:eclipse/myeclipse/ideaMaven包:…

K8s的常用命令以及yaml文件的創建

目錄 一、聲明式管理方法:YAML文件 1、yaml文件簡介 2、yaml和json的主要區別: 3、YAML的語法格式 4、yaml文件組成部分 ①控制器定義 5、查看api資源版本標簽 6、編寫nginx-deployment.yaml資源配置清單 6.1創建資源對象 6.2查看創建的pod資源…

使用python將一段文本寫入一個txt文件中且先格式化文件名

有一段文本內容&#xff0c;有“標題”和“內容”組成。 任務&#xff1a;要將這段文本&#xff0c;存放到一個txt文件中&#xff0c;文件名為當天的日期加上“標題”內容。因為“標題”內可能有/<>之類的&#xff0c;還需要格式化一下。 已經將上述功能都寫成了函數&a…

安卓手機APP開發__近距離無線通信(NFC)概述

安卓手機&#xff21;&#xff30;&#xff30;開發&#xff3f;&#xff3f;近距離無線通信(NFC)概述 概述 近距離無線通信 (NFC) 是一組近距離無線技術&#xff0c;距離通常不超過 4 厘米才能 發起連接。通過 NFC&#xff0c;您可以在 NFC 標簽和 Android 設備之間&#xf…

【Redis】 String類型的內部編碼與使用環境

文章目錄 &#x1f343;前言&#x1f334;內部編碼&#x1f384;典型使用場景&#x1f6a9;緩存功能&#x1f6a9;計數&#xff08;Counter&#xff09;功能&#x1f6a9;共享會話&#xff08;Session&#xff09;&#x1f6a9;驗證碼功能 ?總結 &#x1f343;前言 本篇文章重…

Unity-Sprite Atlas+UGUI系統的運行原理

每日一句&#xff1a;別聽世俗耳語&#xff0c;看自己的風景就好 目錄 SA的原理&#xff1a; SA的優點&#xff1a; SA的缺點&#xff1a; DrawCall是什么&#xff1f; 批處理是什么&#xff1f; 我們先了解一下UGUI系統的運行原理吧&#xff01; 提到圖集優化&#xff0…