遍歷二叉樹最全面講解

前言

這是我聽老師講課做的筆記。
作者:RodmaChen
關注我的csdn博客,更多數據結構與算法知識還在更新
看這篇文章之前可以先看:樹和二叉樹的定義

一. 遍歷二叉樹

1.介紹

  1. 什麼叫做遍歷?
    官方回答:是指沿着某條搜索路線,依次對樹中每個結點均做一
    次且做一次訪問。

​ 通俗回答:每個結點都過一遍

  1. 遍歷的目的非線性結構線性化

    二叉樹是非線性結構,經過一次完整遍歷,可將各結點的非線性排列變爲某種意義的線性序列。

2.遍歷的方式

(1)先(根)序遍歷(NLR/DLR )
基本思想:若二叉樹爲空,則退出,否則

(1) 訪問根結點;

(2) 按先序周遊整個左子樹;

(3) 按先序周遊整個右子樹。

先序遍歷的遞歸算法:(兩部分:出口結束,否者繼續遞減)

在這裏插入圖片描述

基本思想:若二叉樹爲空,則退出,否則

中序遍歷整個左子樹;

訪問根結點;

中序遍歷整個右子樹。

中序遍歷的遞歸算法:

在這裏插入圖片描述

(3) 後(根)序遍歷(LRD/LRN )

基本思想:若二叉樹爲空,則退出,否則
YLEEQO.png

後序遍歷整個左子樹;

後序遍歷整個右子樹;

訪問根結點。

後序遍歷的遞歸算法:

在這裏插入圖片描述

3.二叉樹遍歷的考試方式

  1. 給出一棵樹,寫出先、中、後序

  2. 由NLR 、LNR 、LRN 擴展到NRL 、RNL 、RLN

  3. (1)給出先序+ 中序 寫出 後序
    (先序找根,中序分左右)
    (2)給出後序+ 中序 寫出 先序
    (後序找根,中序分左右)

  4. 考遞歸遍歷算法

事列:

注意:後序:最後一個是根節點

4. 遍歷的應用(重點學習)

(1)建立二叉鏈表(已經有樹,現在是創建鏈表存):掌握要考

基於先序遍歷的構造算法,在其中加入虛結點以示空指針
的位置:ABDøøøCEøøFøø

構造算法

Status CreateBiTree(BiTree &T) {
//按先序次序輸入二叉樹中結點的值(一個字符),空格字符表示空樹,
//構造二又鏈表表示的二叉樹T
scanf(&ch);
if(ch ==’’) T = NULL;
else{
if(!(T = (BiTNode *)malloc(sizeof(BiTNode)))) exit(OVERFLOW);//分配空間
T->data = ch; //生成根結點
CreateBiTree(T -> lchild); //構造左子樹
CreateBiTree(T -> rchild) //構造右子樹
}
return OK;
}// CreateBiTree

(2) 求二叉樹的結點個數重要

調用過程:事列

YLE8l8.png

int count(BiTree T)//計數
{
int lcount,rcount;//左右
if (T==NULL) return 0;
else
{
lcount = count(T -> lchild);//左子樹調用函數返回左子樹的個數
rcount = count(T -> rchild);
return lcount + rcount +1;//加一是根節點
}
}

(3) 求二叉樹葉子結點的個數

修改計數條件,滿足加上,不滿足不加

int countleaf(BiTree T)
{
int lcount,rcount;
if (T==NULL) return 0;
else
{
lcount = countleaf(T -> lchild);
rcount = countleaf(T -> rchild);
if(T->lchild==NULL && T->rchild==NULL)
return lcount + rcount +1;
else
return lcount + rcount;
}}

(4) 求二叉樹度爲1 的結點的個數

int countdeg1(BiTree T)
{
int lcount,rcount;
if (T==NULL) return 0;
else
{
lcount = countdeg1(T -> lchild);
rcount = countdeg1(T -> rchild);
if((T->lchild != NULL && T->rchild == NULL)||(T->lchild ==
NULL && T->rchild != NULL))
return lcount + rcount +1;
else
return lcount + rcount;
}}

(5) 計算二叉樹的深度

int BiTDepth(BiTree T)
{
int ldep,rdep;
if (T==NULL) return 0;
else{
ldep=BiTDepth(T->lchild)+1;//左子樹深度
rdep=BiTDepth(T->rchild)+1;//右子樹深度
return ldep>rdep?ldep:rdep;
}
}

(6) 複製二叉樹

Status CopyBiTree(BiTree &T, BiTree &T1)
{
BiTree p;
if(T){
p=new BiTNode;
if(!p) return ERROR;
p->data=T->data;
T1=p;
CopyBiTree(T->lchild,T1->lchild);
CopyBiTree(T->rchild,T1->rchild);}
else T1=T;
return OK;
}

二.遍歷的非遞歸:(考研要考)

仿照遞歸算法執行過程中遞歸工作棧(利用棧的先進後出一層層遞歸出來)的狀態變化狀況可
直接寫出相應的非遞歸算法。

以中序遍歷爲例:每遇到一個結點就把它推入棧,然後
遍歷其左子樹,若左子樹爲空,則從棧頂退出這個結點並
訪問;按照其右鏈接指示的地址再去周遊該結點的右子樹。

YLEuTA.png

中序遍歷( 左根右) :

d b g e h a c f

Status InOrderTraverse(BiTree T)
{
//採用二叉鏈表存儲結構,Visit是對數據元素操作的應用函數。
//中序遍歷二叉樹T的非遞歸算法,對每個數據元素調用函數Visit。
InitStack(S) ; p=T;
while (p || !StackEmpty(S)) {
if (p) {Push(S,p); p = p->lchild; } // 根指針進棧,遍歷左子樹
else{ //根指針退棧,訪問根結點,遍歷右子樹
Pop(S, p); Visit(p->data);(VIsit輸出值)
p= p-> rchild;
}// else
}// While
return 0K;
} // InOrderTraverse

三.邊學邊練

1、若一棵二叉樹後序遍歷和中序遍歷的序列分別爲:後序
序列爲DHEBFIGCA,中序序列爲DBEHAFCIG,試畫出這棵二 叉樹。

2、(1)已知一棵二叉樹的前序序列和中序序列分別爲 ABDGHCEFI和GDHBAECIF,求其對應的二叉樹。

(2)已知一棵二叉樹的中序序列和後序序列分別爲 BDCEAFHG和DECBHGFA,求其對應的二叉樹。

(3)若前序序列和後序序列均爲AB和BA能否惟一確定 一棵二叉樹。答案:不能

作者:RodmaChen
本人博客:https://blog.csdn.net/weixin_46654114
本人b站求關注:https://space.bilibili.com/391105864
轉載說明:跟我說明,務必註明來源,附帶本人博客連接。

請給我點個贊鼓勵我吧
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章