1. 程式人生 > >二叉樹的前序,中序,後續,遞迴及非遞迴遍歷的python實現

二叉樹的前序,中序,後續,遞迴及非遞迴遍歷的python實現

在計算機科學裡,樹的遍歷(也稱為樹的搜尋)是圖的遍歷的一種,指的是按照某種規則,不重複地訪問某種樹的所有節點的過程。具體的訪問操作可能是檢查節點的值、更新節點的值等。不同的遍歷方式,其訪問節點的順序是不一樣的。

遍歷的種類

遍歷方式的命名,源於其訪問節點的順序。最簡單的劃分:深度優先,廣度優先。
深度優先遍歷又可分為,前序遍歷(pre-order), 中序遍歷(in-order),後序遍歷(post-order)
對於廣度優先而言,遍歷沒有前序中序後序之分:給定一組已排序的子節點,其“廣度優先”的遍歷只有一種唯一的結果。
二叉樹的遞迴演算法相對簡單,非遞迴演算法實現要用到輔助棧,演算法設計非常巧妙。
定義二叉樹結構如下

class BinNode():
    def __init__(self, val):
        self.left = None
        self.right = None
        self.val = val

前序遍歷(pre-order)

訪問順序:根左右

遞迴寫法

def preOrder(sellf, root):
    if root == None:
        return
    print(root.val)
    self.preOrder(root.left)
    self.preOrder(root.right)

非遞迴寫法
preOrder每次都將遇到的節點壓入棧,當左子樹遍歷完畢後才從棧中彈出最後一個訪問的節點,再訪問其右子樹。

def preOrder(self, root):
    if root == None:
        return
    stack = []
    node = root
    while node or stack:
        while node:
            # 從根節點開始,一直找它的左子樹
            print(node.val)
            stack.append(node)
            node = node.left
        # while結束表示當前節點node為空,即前一個節點沒有左子樹了
node = stack.pop() # 開始檢視它的右子樹 node = node.right

中序遍歷(In-order)

訪問順序:左根右

遞迴寫法

def inOrder(self, root):
    if root == None:
        return
    self.inOrder(root.left)
    print(root.val)
    self.inOrder(root.right)

非遞迴寫法
中序的非遞迴遍歷與先序的非遞迴遍歷類似。先序遍歷是先訪問節點,然後再將節點入棧,後中序遍歷則是先入棧,然後節點彈出棧後再訪問。

def inOrder(self,root):
    if root == None:
        return
    stack = []
    while node or stack:
        while node:
            # 從根節點開始,一直找到左子樹
            stack.append(node)
            node = node.left
        # while結束表示當前節點node為空,即前一個節點沒有左子樹了
        node = stack.pop()
        print(node.val)
        node = node.right

後序遍歷

訪問順序:左右根

遞迴寫法

def postOrder(self,root):
    if root == None:
        return
    self.postOrder(root.left)
    self.postOrder(root.right)
    print(root.val)

非遞迴寫法:
從直覺上來說,後序遍歷對比中序遍歷難度要增大很多。因為中序遍歷節點序列有一點的連續性,而後續遍歷則感覺有一定的跳躍性。先左,再右,最後才中間節點;訪問左子樹後,需要跳轉到右子樹,右子樹訪問完畢了再回溯至根節點並訪問之,程式碼如下:

def postOrder(self,root):
    if root == None:
        return
    stack1 = []
    stack2 = []
    node = root
    stack1.append(node)
    while stack1:
    # 這個while迴圈使用者找到後續遍歷的逆序,存在stack2中
        node = stack1.pop()
        if node.left:
            stack1.append(node.left)
        if node.right:
            stack1.append(node.right)
        stack2.append(node)
    while stack2:
        print(stack2.pop().val)

廣度優先遍歷

廣度優先搜尋(Breadth First Search),又叫寬度優先搜尋或橫向優先搜尋,是從根結點開始沿著樹的寬度搜索遍歷。
可以利用佇列實現廣度優先搜尋。

廣度優先遍歷q與深度優先遍歷的區別

廣度優先遍歷與深度優先遍歷的區別在於:廣度優先遍歷是以層為順序,將某一層上的所有節點都搜尋到了之後才向下一層搜尋;而深度優先遍歷是將某一條枝椏上的所有節點都搜尋到了之後,才轉向搜尋另一條枝椏上的所有節點。

from collections import deque
def BFS(self, root):
    if root == None:
        return
    quene = deque()
    node = root
    quene.append(node)
    while quene:
        node = quene.popleft()
        print(node.val)
        if node.left:
            quene.append(node.left)
        if node.right:
            quene.append(node.right)

相關推薦

PAT-A1020:Tree Traversal(的重建及其、後

題目傳送門:https://pintia.cn/problem-sets/994805342720868352/problems/994805485033603072 目錄 題目解釋: 解題思路: ac程式碼: 題目解釋: 給出一棵二叉樹(binary tree)的後

資料結構實驗之八:()求的深度(SDUT 2804)

#include <stdio.h> #include <stdlib.h> #include <string.h> struct node { char data ; struct node *l,*r; }; struct node *cr

資料結構實驗之八:()求的深度

Problem Description 已知一顆二叉樹的中序遍歷序列和後序遍歷序列,求二叉樹的深度。 Input 輸入資料有多組,輸入T,代表有T組資料。每組資料包括兩個長度小於50的字串,第一個字串表示二叉樹的中序遍歷,第二個表示二叉樹的後序遍歷。 Output

2804 資料結構實驗之八:()求的深度

#include<iostream> #include <malloc.h> #include<string.h> using namespace std; struct node { char data;

根據廣義表建立對應(子女兄弟鏈表表示)並由輸出對應廣義表(子女兄弟鏈表表示)的C++實現

ios blog null new 根節點 span name creat nullptr 根據輸入的廣義表建立子女右兄弟鏈的二叉樹表示,該二叉樹對應於廣義表對應的普通樹。先考慮更復雜的情形,如果廣義表中存在共享表,則將其轉換為帶共享子樹的二叉樹表示,每一共享子樹帶有附加頭

js,//後(最大最小值排序)

data nod can ole right unshift func pro node function Node(data,left,right) { this.left=left this.right=right

golang算法

rec == int post order nta rev UC right package main import ( "container/list" "fmt" ) // Binary Tree type Bin

已知求後java實現

  簡單介紹一下思想,先看前序,前序遍歷的第一個節點,就是該樹的根。在中序中找到該根的位置,設為index,在中序遍歷集合中,位於index之前的屬於根的左子樹,位於index之後的屬於根的右子樹。然後,對左右子數,遍

的建立♪♬♫(先後)

1.先序遞迴建立二叉樹 首先要判斷當前節點是否為空節點,不是空節點才可以往下進行; 判斷好了節點不為空,就可以為根節點申請記憶體空間了,併為根節點的資料域賦值; 因為這是先根建立二叉樹,<span style="background-color: rgb(51, 25

後續python實現

在計算機科學裡,樹的遍歷(也稱為樹的搜尋)是圖的遍歷的一種,指的是按照某種規則,不重複地訪問某種樹的所有節點的過程。具體的訪問操作可能是檢查節點的值、更新節點的值等。不同的遍歷方式,其訪問節點的順序是不一樣的。 遍歷的種類 遍歷方式的命名,源於其訪問節點

】已知求後和後

#include<iostream> using namespace std; //已知二叉樹前序遍歷和中序遍歷,求後序遍歷 void binary_tree_postorder(char* preorder,char* inorder,int length){

詳解

只要是搞計算機的,對資料結構中二叉樹遍歷都不陌生,但是如果用到的機會不多那麼就會慢慢淡忘,溫故而之新才是最好的學習方式,現在就重新溫習一下這方面的知識。 首先我想先改變這幾個遍歷的名字(前根序遍歷,中根序遍歷,後根序遍歷);前中後本來就是相對於根結點來說的,少一個字會產生很

POJ2255-已知求後

nbsp def 二叉樹 水題 輸出 ostream -i sin root 水題……也可以不建立二叉樹來做 如果pre[pl:pr]對應in[il:ir],那麽pre[pl]是這棵樹的根,它在in的位置記為root,顯然root在[il,ir]內 那麽二叉樹的左子樹是in

得到後

() level struct OS spa str sel src [] 二叉樹的前序遍歷為:{1,2,4,7,3,5,6,8},中序遍歷為:{4,7,2,1,5,3,8,6},求後序遍歷   # -*- coding:utf-8 -*- class Nod

數據結構35:和後

tdi 代碼 nod 完成 循環 同時 reat pan 設置 遞歸算法底層的實現使用的是棧存儲結構,所以可以直接使用棧寫出相應的非遞歸算法。 先序遍歷的非遞歸算法 從樹的根結點出發,遍歷左孩子的同時,先將每個結點的右孩子壓棧。當遇到結點沒有左孩子的時候,取棧頂的右

、後 /

前語  二叉樹的遍歷是指按一定次序訪問二叉樹中的每一個結點,且每個節點僅被訪問一次。 前序遍歷  若二叉樹非空,則進行以下次序的遍歷:   根節點—>根節點的左子樹—>根節點的右子樹   若要遍歷左子樹和右子樹,仍然需要按照以上次序進行,所以前序遍歷也是一個遞

【演算法】、後相互求法(轉)

二叉樹前序、中序、後序遍歷相互求法 原文地址      今天來總結下二叉樹前序、中序、後序遍歷相互求法,即如果知道兩個的遍歷,如何求第三種遍歷方法,比較笨的方法是畫出來二叉樹,然後根據各種遍歷不同的特性來求,也可以程式設計求出,下面我們分別說明。  

leetcode144 的不同

二叉樹中序遍歷 class Solution { public: vector<int> inorderTraversal(TreeNode* root) { TreeNode* cur=root; vector<int>

解法

遞迴解法很簡單,構建一個輔助函式helper,改變一下其中的兩行程式碼的順序便可實現前序中序後序遍歷,程式碼如下: 前序遍歷(遞迴) vector<int> preorderTraversal(TreeNode* root) { vector<in

已知、後構造(關鍵詞://先//後/先根/根/後根//搜尋/查詢)

已知中序、後序構造二叉樹 遞迴演算法 def buildTree(inorder, postorder): if inorder and postorder: postRootVal = postorder