樹結構--介紹--二叉樹遍歷的遞歸實現

?

目錄

樹?

樹的學術名詞

樹的種類

?二叉樹的遍歷

算法實現

遍歷命名

二叉樹的中序遍歷

二叉樹的后序遍歷

二叉樹的后序遍歷迭代算法

?二叉樹的前序遍歷

二叉樹的前序遍歷迭代算法

?


樹封面

樹?

是一種非線性的數據結構,它是由n(n≥0)個有限節點組成一個具有層次關系的集合。把它叫做“樹”是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的特點:

  • 每個節點有零個或多個子節點;
  • 沒有父節點的節點稱為根節點;
  • 每一個非根節點有且只有一個父節點;
  • 除了根節點外,每個子節點可以分為多個不相交的子樹

image-20220909102214728

樹的學術名詞

  • 根節點(root): 樹的最上層的節點,任何非空的樹都有一個節點
  • 路徑(path): 從起始節點到終止節點經歷過的邊
  • 父親(parent):除了根節點,每個節點的上一層邊連接的節點就是它的父親(節點)
  • 孩子(children): 每個節點由邊指向的下一層節點
  • 兄弟(siblings): 同一個父親并且處在同一層的節點
  • 子樹(subtree): 每個節點包含它所有的后代組成的子樹
  • 葉子節點(leaf node): 沒有孩子的節點成為葉子節點

樹的種類

無序樹:樹中任意節點的子結點之間沒有順序關系,這種樹稱為無序樹,也稱為自由樹;

有序樹:樹中任意節點的子結點之間有順序關系,這種樹稱為有序樹;

二叉樹:每個節點最多含有兩個子樹的樹稱為二叉樹;

滿二叉樹:所有節點均含有兩個子樹的樹被稱為滿二叉樹;

完全二叉樹:除最后一層外,所有層都是滿節點,且最后一層缺右邊連續節點的二叉樹稱為完全二叉樹;

哈夫曼樹(最優二叉樹):帶權路徑最短的二叉樹稱為哈夫曼樹或最優二叉樹。

image-20220912170946925

?二叉樹的遍歷

所謂遍歷(Traversal)是指沿著某條搜索路線,依次對樹中每個結點均做一次且僅做一次訪問

訪問結點所做的操作依賴于具體的應用問題。 遍歷是二叉樹上最重要的運算之一,是二叉樹上進行其它運算之基礎

算法實現

從二叉樹的遞歸定義可知,一棵非空的二叉樹由根結點及左、右子樹這三個基本部分組成。因此,在任一給定結點上,可以按某種次序執行三個操作:

  • 訪問節點的本身(Node)
  • 遍歷該節點的左子樹(L)
  • 遍歷該節點的右子樹 (R)

以上三種操作擁有六種執行順序:

NLR,LNR,LRN,NRL,RNL,RLN。

但是注意前三種次序和后三種次序對稱,所以我們只學習前三種次序

image-20220912185718782

遍歷命名

根據訪問結點操作發生位置命名:

  • NLR:二叉樹的前序遍歷(Preorder Traversal 亦稱(先序遍歷))

    訪問根結點的操作發生在遍歷其左右子樹之前

  • LNR:二叉樹的中序遍歷(Inorder Traversal)

    訪問根結點的操作發生在遍歷其左右子樹之中(間)

  • LRN:二叉樹的后序遍歷(Postorder Traversal)

    訪問根結點的操作發生在遍歷其左右子樹之后

    ?

二叉樹的中序遍歷

若二叉樹非空,則依次執行如下操作:

  1. 遍歷左子樹
  2. 訪問根節點
  3. 遍歷右子樹

image-20220912185750188

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, val=0, left=None, right=None):
#     self.val = val
#     self.left = left
#     self.right = right
class Solution:def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:# 左 根 右def inorder(root : TreeNode):if not root:returninorder(root.left)res.append(root.val)inorder(root.right)res = list()inorder(root)return res

?

二叉樹的后序遍歷

若二叉樹非空,則依次執行如下操作:

  1. 遍歷左子樹
  2. 遍歷右子樹
  3. 訪問根節點

image-20220912185833626

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, val=0, left=None, right=None):
#     self.val = val
#     self.left = left
#     self.right = right
class Solution:def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:# 后序遍歷的順序:左 右 根def postorder(root : TreeNode):if not root:returnpostorder(root.left)postorder(root.right)res.append(root.val)res = list()postorder(root)return res

二叉樹的后序遍歷迭代算法

  1. 建立一個棧,用來存儲節點。

  2. 根據根右左的順序將節點依次壓入棧中,在壓入棧中的同時,按照順序把節點里的元素依次壓入棧中。輸出完畢之后按照順序彈棧。

  3. 將答案數組進行反轉,得到左右根順序的數組

  4. 輸出答案

    image-20220913114354933

期望結果:[9,5,7,4,3]

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, val=0, left=None, right=None):
#     self.val = val
#     self.left = left
#     self.right = right
class Solution:def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:res = []stack = []while root or stack:while root:res.append(root.val)stack.append(root)root = root.rightroot = stack.pop().left #根 右 左的順序res.reverse() return res

?二叉樹的前序遍歷

若二叉樹非空,則依次執行如下操作:

  1. 訪問根節點

  2. 遍歷左子樹

  3. 遍歷右子樹

    image-20220912185519144

    ?

    class Solution:def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:# 創建一個集合存儲數據res = []def preorder(root:TreeNode):# 判斷root是否有值if not root:returnelse:# 獲取根節點res.append(root.val)# 獲取左節點preorder(root.left)# 獲取右節點preorder(root.right)preorder(root)return res
    

    二叉樹的前序遍歷迭代算法

  4. 建立一個棧,用來存儲節點。
  5. 根據左右根的順序將節點依次壓入棧中,在壓入棧中的同時,按照順序把節點里的元素依次壓入棧中。輸出完畢之后按照順序彈棧。
  6. 輸出答案。
class Solution:def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:# 創建res存儲結果res = []stack = [] # 存儲分支節點# 只要root有數據 或者stack的數據while root or stack:# 只要root有數據,第一輪循環把左節點搞定while root:res.append(root.val)stack.append(root)# 獲取左節點root = root.left# 取出右節點,遍歷root = stack.pop().rightreturn res

?

?

?

?

?

?

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

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

相關文章

Docker安裝 elasticsearch-head

目錄 前言安裝elasticsearch-head步驟1:準備1. 安裝docker2. 搜索可以使用的鏡像。3. 也可從docker hub上搜索鏡像。4. 選擇合適的redis鏡像。 步驟2:拉取elasticsearch-head鏡像拉取鏡像查看已拉取的鏡像 步驟3:創建容器創建容器方式1&#…

SpringBoot復習:(28)【前后端不分離】自定義View

一、自定義View package cn.edu.tju.view;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Comp…

C# --- Case Study

C# --- Case Study C# — Mongo數據庫事務的應用 C# — 如何解析Json文件并注入MongoDB C# — MongoDB如何安全的替換Collection

百度翻譯API整合SpringBoot

案例背景,按照官方給的Demo,實在是太啰嗦了, 大致步驟 封裝數據>簽名>發送請求, 仔細一看劈里啪啦一大堆,最后還要手動關流關連接,難道整合到SpringBoot項目里面我還得為內存管理考慮 所以就有了如下需求 使用 RestTemplate的對象進行發送請求數據,RestTemplate由s…

Redis緩存刪除略和內存淘汰策略及LRU

1、Redis內存若在配置文件中未設置,內存會無限制增長,直到超出物理內存,拋出out of memory內存耗盡異常 解決方法,調整maxmemory參數,一般設置為物理內存的3/4,并且添加緩存刪除策略 2、Redis對于設置了過…

項目經理的會議之道:全參與還是精選參與?

引言 在項目管理中,會議是一個常見的工具,用于溝通信息、解決問題、做出決策等。然而,項目經理是否需要參加所有的會議呢?這是一個值得深思的問題。作為項目經理,我們需要權衡會議的重要性和我們的時間管理。我們不能…

【第一階段】kotlin的函數

函數頭 fun main() {getMethod("zhangsan",22) }//kotlin語言默認是public,kotlin更規范,先有輸入( getMethod(name:String,age:Int))再有輸出(Int[返回值]) private fun getMethod(name:String,age:Int): Int{println("我叫…

Elasticsearch集群shard過多后導致的性能問題分析

1.問題現象 上午上班以后發現ES日志集群狀態不正確,集群頻繁地重新發起選主操作。對外不能正常提供數據查詢服務,相關日志數據入庫也產生較大延時 2.問題原因 相關日志 查看ES集群日志如下: 00:00:51開始集群各個節點與當時的master節點…

Playwright快速上手-1

前言 隨著近年來對UI自動化測試的要求越來越高,,功能強大的測試框架也不斷的涌現。本系列主講的Playwright作為一款新興的端到端測試框架,憑借其獨特優勢,正在逐漸成為測試工程師的熱門選擇。 本系列文章將著重通過示例講解 Playwright python開發環境的搭建 …

Linux Day07

一、僵死進程 1.1僵死進程產生的原因 子進程先于父進程結束, 而父進程沒有獲取子進程退出碼,釋放子進程占用的資源,此時子進程將成為一個僵死進程。 在第一個框這里時父進程子進程都沒有結束,顯示其pid 父進程是2349,子進程是235…

【Nginx】Nginx網站服務

國外主流還是使用apache;國內現在主流是nginx(并發能力強,相對穩定) nginx:高性能、輕量級的web服務軟件 特點: 1.穩定性高(沒apache穩); 2.系統資源消耗比較低&#xf…

Failed to set locale, defaulting to C.UTF-8 或者中文系統語言轉英文系統語言

CentOS 8中執行命令,出現報錯:Failed to set locale, defaulting to C.UTF-8報錯原因: 1、沒有安裝相應的語言包。2、沒有設置正確的語言環境。 解決方法1:安裝語言包 設置語言環境需使用命令 localelocale -a 命令,查…

代碼隨想錄day02

977.有序數組的平方 ● 力扣題目鏈接 ● 給你一個按 非遞減順序 排序的整數數組 nums,返回 每個數字的平方 組成的新數組,要求也按 非遞減順序 排序。 思路 ● 暴力排序,時間復雜度O(n nlogn) ● 使用雙指針,時間復雜度O(n) …

Vue中使用v-bind:class動態綁定多個類名

Vue.js是一個流行的前端框架,它可以幫助開發者構建動態交互的UI界面。在Vue.js開發中,經常需要動態綁定HTML元素的class(類名)屬性,以改變元素的外觀和行為。本文將介紹采用v-bind:class指令在Vue中如何動態綁定多個類…

【大數據】-- 本地部署 Flink kubernetes operator

目錄 1.說明 1.1 版本 1.2 kubernetes 環境 1.3 參考 2.安裝步驟 2.1 安裝本地 kubernetes 環境

判斷鏈表有環的證明

目錄 1.問題 2.證明 3.代碼實現 1.問題 給你一個鏈表的頭節點 head ,判斷鏈表中是否有環。 如果鏈表中有某個節點,可以通過連續跟蹤 next 指針再次到達,則鏈表中存在環。 為了表示給定鏈表中的環,評測系統內部使用…

TansUNet代碼理解

首先通過論文中所給的圖片了解網絡的整體架構: vit_seg_modeling部分 模塊引入和定義相關量: # codingutf-8 # __future__ 在老版本的Python代碼中兼顧新特性的一種方法 from __future__ import absolute_import from __future__ import division fr…

新基建助推數字經濟,CosmosAI率先布局AI超算租賃新紀元

倫敦, 8月14日 - 在英國倫敦隆重的Raffles OWO舉辦的歐盟數字超算新時代戰略合作簽約儀式,CosmosAI、Infinite Money Fund與Internet Research Lab三方強強聯手,達成了歷史性的合作協議,共同邁向超算租賃新紀元。 ? 這次跨界的合作昭示了全球…

Session基礎

文章目錄 什么是Sessionsession與cookie的區別和聯系Session的存Session的取 什么是Session 服務器為每個用戶瀏覽器創建一個會話對象(session對象),一個瀏覽器只能產生一個session當新建一個窗口訪問服務器時,還是原來的那個ses…

VR家裝提升用戶信任度,線上體驗家裝空間感

近些年,VR家裝逐漸被各大裝修公司引入,VR全景裝修的盛行,大大增加了客戶“所見即所得”的沉浸式體驗感,不再是傳統二維平面的看房模式,而是讓客戶通過視覺、聽覺、交互等功能更加真實的體驗家裝后的效果。 對于傳統家裝…