【初階數據結構】樹與二叉樹:從零開始的奇幻之旅

在這里插入圖片描述

初階數據結構相關知識點可以通過點擊以下鏈接進行學習一起加油!
時間與空間復雜度的深度剖析深入解析順序表:探索底層邏輯深入解析單鏈表:探索底層邏輯深入解析帶頭雙向循環鏈表:探索底層邏輯深入解析棧:探索底層邏輯
深入解析隊列:探索底層邏輯深入解析循環隊列:探索底層邏輯

本篇將從樹與二叉樹相關概念進行入手,幫助我們接下二叉樹更進一步的學習。

請添加圖片描述
Alt

🌈個人主頁:是店小二呀
🌈C語言筆記專欄:C語言筆記
🌈C++筆記專欄: C++筆記
🌈初階數據結構筆記專欄: 初階數據結構筆記

🌈喜歡的詩句:無人扶我青云志 我自踏雪至山巔
請添加圖片描述

文章目錄

  • 一、樹概念及結構
    • 1.1 樹的相關概念
  • 二、樹的存儲表示
  • 三、二叉樹概念
    • 3.1 現實中的二叉樹(見到都要拜幾下)
  • 四、特殊的二叉樹
    • 4.1 不屬于完全二叉樹的情況
  • 五、二叉樹的存儲結構
    • 5.1 順序存儲
    • 5.2 父子節點間下標規律關系(重要)
    • 5.3 鏈式存儲
    • 5.4 小總結

一、樹概念及結構

樹是一種非線性的數據結構,它是由n(n>=0)個有限節點組成一個具有層次關系的集合,然而樹在實踐中價值不大,但是二叉樹實踐價值比較大(這種集合稱為樹的理由,是它是根朝上,而葉朝下,看起來很像樹)

  • 有一個特殊的節點,稱為根節點,根節點沒有前驅節點
  • 除根節點外,其余節點被分成M(M>0)個互不相交的集合T1、T2、....、Tm,其中每一個集合Ti(1<=i<=m)又是一顆結構與樹類似的子樹。每顆子樹的根節點有且只有一個前驅,可有0個或多個后繼。
  • 樹是遞歸定義,與此同時需要注意。在樹形結構中子樹之間不能有交集,否則就不是樹形結構

在這里插入圖片描述

在這里插入圖片描述

1.1 樹的相關概念

在這里插入圖片描述

  • 節點的度:一個節點含有的子樹的個數稱為該節點的度; 如上圖:A的為6
  • 葉節點或終端節點:度為0的節點稱為葉節點; 如上圖:B、C、H、I…等節點為葉節點
  • 非終端節點或分支節點:度不為0的節點; 如上圖:D、E、F、G…等節點為分支節點
  • 雙親節點或父節點:若一個節點含有子節點,則這個節點稱為其子節點的父節點; 如上圖:A是B的父節點
  • 孩子節點或子節點:一個節點含有的子樹的根節點稱為該節點的子節點; 如上圖:B是A的孩子節點
  • 兄弟節點:具有相同父節點的節點互稱為兄弟節點; 如上圖:B、C是兄弟節點
  • 樹的度:一棵樹中,最大的節點的度稱為樹的度; 如上圖:樹的度為6
  • 節點的層次:從根開始定義起,根為第1層,根的子節點為第2層,以此類推
  • 樹的高度或深度:樹中節點的最大層次; 如上圖:樹的高度為4
  • 堂兄弟節點:雙親在同一層的節點互為堂兄弟;如上圖:H、I互為兄弟節點
  • 節點的祖先:從根到該節點所經分支上的所有節點;如上圖:A是所有節點的祖先
  • 子孫:以某節點為根的子樹中任一節點都稱為該節點的子孫。如上圖:所有節點都是A的子孫
  • 森林:由m(m>0)棵互不相交的樹的集合稱為森林

二、樹的存儲表示

由于樹狀結構相對線性表復雜,存儲方式也更加麻煩,既要保存值域,也要保存好結點和結點之間的關系。

以下根據之前知識得到的幾種方法

  • 每個孩子都有一個地址,可以通過指針數組存儲數據(空間是固定,申請新空間有代價和空間情況問題出現)
  • 對于第一種方法優化,將指針數組改用為順序表存儲孩子,解決了空間固定的問題
  • 推薦常用的解法:左孩子右兄弟法(老大帶著老二,老二帶著老三,不用雙親累)
typedef int DataType;
struct Node
{struct Node* _firstChild1; // 第一個孩子結點struct Node* _pNextBrother; // 指向其下一個兄弟結點DataType _data; // 結點中的數據域
};

在這里插入圖片描述

當然不局限以上幾種方式,還有雙親表示法,孩子表示法、孩子雙親表示法以及孩子兄弟表示法等。我們這里就簡單的了解其中最常用的孩子兄弟表示法

三、二叉樹概念

一顆二叉樹是節點的一個有限集合,該集合可能有兩種情況

  1. 空樹
  2. 由一個根節點加上兩顆別稱為左子樹和右子樹的二叉樹組成(子樹可能為空樹)

在這里插入圖片描述

從圖中可以得出兩個結論:

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

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

注意:對于任意的二叉樹都是通過下列幾種情況組成的(空樹的情況最容易忘記)

在這里插入圖片描述

3.1 現實中的二叉樹(見到都要拜幾下)

在這里插入圖片描述

四、特殊的二叉樹

  • 滿二叉樹:一個二叉樹,如果每一個層的節點數都達到最大值,則這個二叉樹為滿二叉樹。換言之一個二叉樹的層次為K,且節點總數是2K-1,則它就是滿二叉樹
  • 完全二叉樹:完全二叉樹是效率很高的數據結構,完全二叉樹是由滿二叉樹而引出的。對于高度為K,有n個節點的二叉樹,當且僅當每一個節點都與高度為K的滿二叉樹中編號從1至n的結點一一對應時稱之為完全二叉樹。

簡單概括下:

  • 滿二叉樹的每一層都是滿的

  • 完全二叉樹如果高度是n,那么前n-1個是滿的,最后一層不一定滿,但是從左到右必須是連續

  • 完全二叉樹是效率很高的數據結構,滿二叉樹是一種特殊的完全二叉樹

  • 滿二叉樹是完全二叉樹的充分必要條件

在這里插入圖片描述

4.1 不屬于完全二叉樹的情況

這種就是普通的二叉樹,從左到右不是連續的。

在這里插入圖片描述

五、二叉樹的存儲結構

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

5.1 順序存儲

順序結構存儲就是使用數組來存儲,一般使用數組只適合表示完全二叉樹,因為不是滿二叉樹會有空間的浪費,對此現實中使用中只有堆才會使用數組來存儲。二叉樹順序存儲在物理上是一個數組,在邏輯上是一顆二叉樹,在接下來做題我們需要根據物理上是數組,邏輯上是二叉樹配合去解出一道題目。

在這里插入圖片描述

5.2 父子節點間下標規律關系(重要)

  • leftchild = parent * 2 + 1;

  • rightchild = paretn * 2 +2;

  • parent = (child - 1) / 2;(不區分左右孩子)

  • 對于第三點,個人推理下,leftchild下標拆為leftchild- 11,對于leftchild-1parent下標兩倍,對于(child - 1) / 2運算將leftchild拆出來為1部分單獨除于2取整數為0,leftchild -1部分可以看成leftchild,而且rightchild與leftchild相差1,由于rightchild = leftchild - 1和通過上面leftchild - 1 ~= leftchild,可以推理出rightchild = leftchild(在進行/2運算,取整數情況下)

5.3 鏈式存儲

二叉樹的鏈式存儲結構是指,用鏈表來表示一棵二叉樹,即用鏈來指示元素的邏輯關系。 通常的方法是鏈表中每個結點由三個域組成,數據域和左右指針域,左右指針分別用來給出該結點左孩子和右孩子所在的鏈結點的存儲地址 。鏈式結構又分為二叉鏈和三叉鏈,當前我們學習中一般都是二叉鏈,后面學到高階數據結構如紅黑樹等會用到三叉鏈

在這里插入圖片描述
**加粗樣式**

typedef int BTDataType;
// 二叉鏈
struct BinaryTreeNode
{struct BinTreeNode* _pLeft; // 指向當前節點左孩子struct BinTreeNode* _pRight; // 指向當前節點右孩子BTDataType _data; // 當前節點值域
}
// 三叉鏈
struct BinaryTreeNode
{struct BinTreeNode* _pParent; // 指向當前節點的雙親struct BinTreeNode* _pLeft; // 指向當前節點左孩子struct BinTreeNode* _pRight; // 指向當前節點右孩子BTDataType _data; // 當前節點值域
}

5.4 小總結

順序結構存儲就是通過數組進行存儲,一般使用數組只適合完全二叉樹,非完全二叉樹就不適合數組結構存儲,普通二叉樹只適合鏈式結構存儲。但是在現實中使用堆才會使用數組來存儲,大部分還是通過鏈式結構存儲。

原因在于:

  1. 首先我們要知道,二叉樹擁有其特殊的邏輯結構,不同于其他數據結構適合堆數據的增刪查改,因為在于開辟的空間消耗大,邏輯也更加復雜,如果使用如此復雜的結構去存儲數據,不是沒有多少價值的,這樣子不如一開始就采用順序表進行存儲數據。同時一般而言,二叉樹的結構是遞歸式,用非遞歸實現更加麻煩,
  2. 普通二叉樹中可能存儲元素密度很低,連續存儲的結構會造成大量的空間浪費
  3. 堆是根據"堆屬性"來排序,"堆屬性"決定了樹中結點的位置(在下面堆的介紹有說明)

以上就是本篇文章的所有內容,在此感謝大家的觀看!這里是店小二初階數據結構筆記,希望對你在學習初階數據結構中有所幫助!
請添加圖片描述

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

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

相關文章

day10:03 一文搞懂encode和encoding的區別

在Python中&#xff0c;處理字符串時經常會遇到encode()方法和encoding參數&#xff0c;它們都與字符串的編碼和解碼有關&#xff0c;但用途和上下文有所不同。下面通過案例來解釋它們的關系和區別。 1. encode() 方法 encode()方法是字符串&#xff08;str&#xff09;類型的…

《簡歷寶典》08 - 簡歷中“教育背景”模塊如何揚長避短

目錄 1 本文概述 2 必須寫的信息 3 學歷的優勢凸顯 4 專業的重要性 5 如果所學專業與當前求職的職位不匹配 6 在校期間獲得的獎項和證書 7 最后 1 本文概述 前兩節我們把個人信息模塊做了拆分講解&#xff0c;分為必寫的信息項和根據個人情況酌情添加的信息項&#xff0…

51單片機:如何使用串口波特率計算器及其詳解

目錄 一、如何使用串口波特率計算器 1.以此為例: 2.生成代碼如下: 3.需要手動配置中斷系統 1.原理圖 2.配置代碼 二、如何理解軟件生成的波特率 1.以該代碼為例子進行分析 2.串口模式圖 三、如何計算波特率 參考STC89C52手冊P235 四、如何調用串口中斷函數 一、如何…

HBase 在統一內容平臺業務的優化實踐

作者&#xff1a;來自 vivo 互聯網服務器團隊-Leng Jianyu、Huang Haitao HBase是一款開源高可靠性、擴展性、高性能和靈活性的分布式非關系型數據庫&#xff0c;本文圍繞數據庫選型以及使用HBase的痛點展開&#xff0c;從四個方面對HBase的使用進行優化&#xff0c;取得了一些…

36. Adam 算法詳解

Adam&#xff08;Adaptive Moment Estimation&#xff09;是一種結合動量法和自適應學習率的優化算法&#xff0c;自2014年提出以來&#xff0c;迅速成為深度學習中最流行和常用的優化算法之一。Adam算法的核心思想是利用梯度的一階動量和二階動量來動態調整學習率&#xff0c;…

基于jeecgboot-vue3的Flowable流程-集成仿釘釘流程(五)仿釘釘流程的json數據保存與顯示

因為這個項目license問題無法開源&#xff0c;更多技術支持與服務請加入我的知識星球。 1、需要做一個界面保存與顯示仿釘釘的流程&#xff0c;先建一個表&#xff0c;用online建 2、通過上面生成代碼&#xff0c;放入到相應的前后端工程里 3、修改前端仿釘釘流程的設計功能&a…

spark基于Spark的對招聘信息的分析與設計-計算機畢業設計源碼50716

目 錄 摘要 1 緒論 1.1 研究背景 1.2 研究意義 1.3論文結構與章節安排 2 系統分析 2.1 可行性分析 2.2.1 數據新增流程 2.2.2 數據刪除流程 2.3 系統功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系統用例分析 2.5本章小結 3 系統總體設計 3.1 系統架構設…

Vue2/Vue3實現全局/局部添加防篡改水印的效果。刪除元素無效!更改元素屬性無效!支持圖片、元素、視頻等等。

水印目的 版權保護:水印可以在圖片、文檔或視頻中嵌入作者、品牌或版權所有者的信息,以防止未經授權的復制、傳播或使用。當其他人使用帶有水印的內容時,可以追溯到原始作者或版權所有者,從而加強版權保護。 身份識別:水印可以用作作者或品牌的標識符,使觀眾能夠輕松識…

springboot對ZonedDateTime返回結果json是string-源碼分析

springboot對ZonedDateTime返回結果json是string-源碼分析 application/json格式默認使用ObjectMapper實例進行序列化ObjectMapper自動注入分析springboot關于jackson配置 java.time.ZonedDateTime application/json格式默認使用ObjectMapper實例進行序列化 controller返回后&…

人形機器人的理想與現實

李開復曾提到過一個AI界流傳的“騙子又來了曲線”。 人會不斷給機器進行“是否具有人類智能”的鑒定&#xff0c;而這個過程&#xff0c;總是從被人工智能在某些領域的驚艷表現震撼&#xff0c;到逐漸認識到當時的人工智能還有各種局限&#xff0c;以至于產生巨大心理落差。 近…

html js 3d z軸移動 實現星空

用chatgpt還有kimi 讓實現動畫效果的星空,都太垃圾了 不是y軸移動,就是x軸移動, 我要z軸移動,他們就是搞不出來, ai寫代碼還有很長的路。 <!DOCTYPE html> <meta charset="utf-8" /> <head> <title>ai相關博客</title> </h…

【操作系統】手把手帶你搭建DNS服務器!

DNS服務器 DNS服務器指域名系統或者域名服務。域名系統為Internet上的主機分配域名地址和IP地址&#xff0c;用戶使用域名地址&#xff0c;該系統就會自動把域名地址轉為IP地址。域名服務是運行域名系統的Internet工具。執行域名服務的服務器稱之為DNS服務器&#xff0c;通過DN…

51單片機嵌入式開發:8、 STC89C52RC 操作LCD1602原理

STC89C52RC 操作LCD1602原理 1 LCD1602概述1.1 LCD1602介紹1.2 LCD1602引腳說明1.3 LCD1602指令介紹 2 LCD1602外圍電路2.1 LCD1602接線方法2.2 LCD1602電路原理 3 LCD1602軟件操作3.1 LCD1602顯示3.2 LCD1602 protues仿真 4 總結 1 LCD1602概述 1.1 LCD1602介紹 LCD1602是一種…

maven——(重要)手動創建,構建項目

創建項目 手動按照maven層級建好文件夾&#xff0c;并寫上java&#xff0c;測試代碼和pom文件 構建項目 在dos窗口中執行如下命令 compile編譯 當前maven倉庫中什么都沒有。 在pom所在層級下&#xff0c;執行&#xff1a; mvn compile 就開始顯示下面這些&#xff0c;…

數據庫-ubuntu環境下安裝配置mysql

文章目錄 什么是數據庫&#xff1f;一、ubuntu環境下安裝mysql二、配置mysql配置文件1.先登上root賬號2.配置文件的修改show engines \G; mysql和mysqld數據庫的基礎操作登錄mysql創建數據庫顯示當前數據庫使用數據庫創建表插入students表數據打印students表數據select * from …

前端使用Vue和Element實現可拖動彈框效果,且不影響底層元素操作,Cesium作為底圖(可拖拽的視頻實時播放彈框,底層元素可以正常操作)

簡述&#xff1a;在前端開發中&#xff0c;彈框和實時視頻播放是常見的需求。這里來簡單記錄一下&#xff0c;如何使用Vue.js和Element UI實現一個可拖動的彈框&#xff0c;并在其中播放實時視頻。同時&#xff0c;確保在拖拽彈框時&#xff0c;底層元素仍然可以操作。這里來記…

vue 畫二維碼及長按保存

需求 想要做如下圖的二維碼帶文字&#xff0c;且能夠長按保存 前期準備 一個canvas安裝qrcode&#xff08;命令&#xff1a;npm i qrcode&#xff09; 畫二維碼及文字 初始化畫布 <template><div><canvas ref"canvas" width"300" he…

JAVASE進階day07(泛型,集合,Set,TreeSet,枚舉,數據結構)

泛型 1.泛型的基本使用 限制集合存儲的數據類型 package com.lu.day07.generics;/*** 定義了一個泛型類* E 泛型通配字母(不固定代替真實數據類型A-Z都可以)* 常見的泛型通配字母:* E:element 元素* T:type 類型* R:return 返回值類型* K:key 鍵* …

14.爬蟲---Selenium 經典動態渲染工具的使用

14.Selenium 經典動態渲染工具的使用 1.查看chrome瀏覽器版本2.ChromeDriver 安裝3.Selenium 安裝4.驗證安裝5.基本用法5.1啟動瀏覽器5.2導航到頁面5.3查找元素5.3.1單個元素 find_element5.3.2多個元素 find_elements 5.4 執行操作5.5 動作鏈ActionChains5.6 執行 JavaScript …

Python基礎語法:運算符詳解(算術運算符、比較運算符、邏輯運算符、賦值運算符)②

文章目錄 Python中的運算符詳解一、算術運算符二、比較運算符三、邏輯運算符四、賦值運算符五、綜合示例結論 Python中的運算符詳解 在Python編程中&#xff0c;運算符用于執行各種操作&#xff0c;例如算術計算、比較、邏輯判斷和賦值。了解并掌握這些運算符的使用方法是編寫…