前言
這是我聽老師講課做的筆記。
作者:RodmaChen
關注我的csdn博客,更多數據結構與算法知識還在更新
看這篇文章之前可以先看:樹和二叉樹的定義
一. 遍歷二叉樹
1.介紹
- 什麼叫做遍歷?
官方回答:是指沿着某條搜索路線,依次對樹中每個結點均做一
次且做一次訪問。
通俗回答:每個結點都過一遍
-
遍歷的目的: 非線性結構線性化。
二叉樹是非線性結構,經過一次完整遍歷,可將各結點的非線性排列變爲某種意義的線性序列。
2.遍歷的方式
(1)先(根)序遍歷(NLR/DLR )
基本思想:若二叉樹爲空,則退出,否則
(1) 訪問根結點;
(2) 按先序周遊整個左子樹;
(3) 按先序周遊整個右子樹。
先序遍歷的遞歸算法:(兩部分:出口爲空結束,否者繼續遞減)
基本思想:若二叉樹爲空,則退出,否則
中序遍歷整個左子樹;
訪問根結點;
中序遍歷整個右子樹。
中序遍歷的遞歸算法:
(3) 後(根)序遍歷(LRD/LRN )
後序遍歷整個左子樹;
後序遍歷整個右子樹;
訪問根結點。
後序遍歷的遞歸算法:
3.二叉樹遍歷的考試方式
-
給出一棵樹,寫出先、中、後序
-
由NLR 、LNR 、LRN 擴展到NRL 、RNL 、RLN
-
(1)給出先序+ 中序 寫出 後序
(先序找根,中序分左右)
(2)給出後序+ 中序 寫出 先序
(後序找根,中序分左右) -
考遞歸遍歷算法
注意:後序:最後一個是根節點
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) 求二叉樹的結點個數(重要)
調用過程:事列
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;
}
二.遍歷的非遞歸:(考研要考)
仿照遞歸算法執行過程中遞歸工作棧(利用棧的先進後出一層層遞歸出來)的狀態變化狀況可
直接寫出相應的非遞歸算法。
以中序遍歷爲例:每遇到一個結點就把它推入棧,然後
遍歷其左子樹,若左子樹爲空,則從棧頂退出這個結點並
訪問;按照其右鏈接指示的地址再去周遊該結點的右子樹。
中序遍歷( 左根右) :
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
轉載說明:跟我說明,務必註明來源,附帶本人博客連接。
請給我點個贊鼓勵我吧