【練習】二叉樹的遍歷
1.按層遍歷
void oper(ChainBinTree *p) //操作二叉樹結點資料
{
printf("%c ",p->data); //輸出資料
return;
}
void BinTree_Level(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //按層遍歷
{
ChainBinTree *p;
ChainBinTree *q[QUEUE_MAXSIZE]; //定義一個順序棧
int head=0,tail=0;//隊首、隊尾序號
if(bt)//若隊首指標不為空
{
tail=(tail+1)%QUEUE_MAXSIZE;//計算迴圈佇列隊尾序號
q[tail] = bt;//將二叉樹根指標進隊
}
while(head!=tail) //佇列不為空,進行迴圈
{
head=(head+1)%QUEUE_MAXSIZE; //計算迴圈佇列的隊首序號
p=q[head]; //獲取隊首元素
oper(p);//處理隊首元素
if(p->left!=NULL) //若結點存在左子樹,則左子樹指標進隊
{
tail=(tail+1)%QUEUE_MAXSIZE;//計算迴圈佇列的隊尾序號
q[tail]=p->left;//將左子樹指標進隊
}
if(p->right!=NULL)//若結點存在右孩子,則右孩子結點指標進隊
{
tail=(tail+1)%QUEUE_MAXSIZE;//計算迴圈佇列的隊尾序號
q[tail]=p->right;//將右子樹指標進隊
}
}
return;
}
在整個佇列的處理中,首先從根節點開始,將每層的結點逐步進入佇列,這樣就可以得到按層遍歷的效果。
2.遞迴遍歷二叉樹
先序遍歷
void BinTree_DLR(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //先序遍歷
{
if(bt)//樹不為空,則執行如下操作
{
oper(bt); //處理結點的資料
BinTree_DLR(bt->left,oper);
BinTree_DLR(bt->right,oper);
}
return;
}
中序遍歷
void BinTree_LDR(ChainBinTree *bt,void(*oper)(ChainBinTree *p)) //中序遍歷
{
if(bt)//樹不為空,則執行如下操作
{
BinTree_LDR(bt->left,oper); //中序遍歷左子樹
oper(bt);//處理結點資料
BinTree_LDR(bt->right,oper); //中序遍歷右子樹/
}
return;
}
後序遍歷
void BinTree_LRD(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //後序遍歷
{
if(bt)
{
BinTree_LRD(bt->left,oper); //後序遍歷左子樹
BinTree_LRD(bt->right,oper); //後序遍歷右子樹/
oper(bt); //處理結點資料
}
return;
}
3.非遞迴遍歷二叉樹
利用棧可以實現遍歷二叉樹的非遞迴演算法。
先序遍歷
void PreOrderTraverse2(BiTree T)
/*先序遍歷二叉樹的非遞迴實現*/
{
BiTree stack[MaxSize]; /*定義一個棧,用於存放結點的指標*/
int top; /*定義棧頂指標*/
BitNode *p; /*定義一個結點的指標*/
top=0; /*初始化棧*/
p=T;
while(p!=NULL||top>0)
{
while(p!=NULL) /*如果p不空,訪問根結點,遍歷左子樹*/
{
printf("%2c",p->data); /*訪問根結點*/
stack[top++]=p; /*將p入棧*/
p=p->lchild; /*遍歷左子樹*/
}
if(top>0) /*如果棧不空*/
{
p=stack[--top]; /*棧頂元素出棧*/
p=p->rchild; /*遍歷右子樹*/
}
}
}
中序遍歷
void InOrderTraverse2(BiTree T)
/*中序遍歷二叉樹的非遞迴實現*/
{
BiTree stack[MaxSize]; /*定義一個棧,用於存放結點的指標*/
int top; /*定義棧頂指標*/
BitNode *p; /*定義一個結點的指標*/
top=0; /*初始化棧*/
p=T;
while(p!=NULL||top>0)
{
while(p!=NULL) /*如果p不空,訪問根結點,遍歷左子樹*/
{
stack[top++]=p; /*將p入棧*/
p=p->lchild; /*遍歷左子樹*/
}
if(top>0) /*如果棧不空*/
{
p=stack[--top]; /*棧頂元素出棧*/
printf("%2c",p->data); /*訪問根結點*/
p=p->rchild; /*遍歷右子樹*/
}
}
}
後序遍歷
void PostOrderTraverse2(BiTree T)
/*後序遍歷二叉樹的非遞迴實現*/
{
BiTree stack[MaxSize]; /*定義一個棧,用於存放結點的指標*/
int top; /*定義棧頂指標*/
BitNode *p,*q; /*定義結點的指標*/
top=0; /*初始化棧*/
p=T,q=NULL; /*初始化結點的指標*/
while(p!=NULL||top>0)
{
while(p!=NULL) /*如果p不空,訪問根結點,遍歷左子樹*/
{
stack[top++]=p; /*將p入棧*/
p=p->lchild; /*遍歷左子樹*/
}
if(top>0) /*如果棧不空*/
{
p=stack[top-1]; /*取棧頂元素*/
if(p->rchild==NULL||p->rchild==q) /*如果p沒有右孩子結點,或右孩子結點已經訪問過*/
{
printf("%2c",p->data); /*訪問根結點*/
q=p;
p=NULL;
top--;
}
else
p=p->rchild;
}
}
}
相關文章
- 個人練習之二叉樹的前序遍歷二叉樹
- 二叉樹的遍歷二叉樹
- 二叉樹遍歷二叉樹
- 二叉樹---遍歷二叉樹
- 144.二叉樹的前序遍歷145.二叉樹的後序遍歷 94.二叉樹的中序遍歷二叉樹
- 完全二叉樹的遍歷二叉樹
- 玩轉二叉樹(樹的遍歷)二叉樹
- 二叉樹遍歷方法二叉樹
- 二叉樹遍歷 -- JAVA二叉樹Java
- C++樹——遍歷二叉樹C++二叉樹
- 根據二叉樹的前序遍歷和中序遍歷輸出二叉樹;二叉樹
- 二叉樹的按層遍歷二叉樹
- 二叉樹的遍歷實現二叉樹
- 二叉樹的層序遍歷二叉樹
- 二叉樹的遍歷筆記二叉樹筆記
- 程式碼隨想錄演算法訓練營day14 | leetcode 144. 二叉樹的前序遍歷、145. 二叉樹的後序遍歷、94. 二叉樹的中序遍歷演算法LeetCode二叉樹
- 【LeetCode-二叉樹】二叉樹前序遍歷LeetCode二叉樹
- 6.14-二叉樹遍歷二叉樹
- 二叉樹--後序遍歷二叉樹
- 迴圈遍歷二叉樹二叉樹
- 二叉樹四種遍歷二叉樹
- 二叉樹的遍歷 → 不用遞迴,還能遍歷嗎二叉樹遞迴
- 練習-jq的遍歷
- 144. 二叉樹的前序遍歷二叉樹
- 二叉樹的遍歷 (迭代法)二叉樹
- 二叉樹的遍歷及應用二叉樹
- 什麼是遍歷二叉樹,JavaScript實現二叉樹的遍歷(遞迴,非遞迴)二叉樹JavaScript遞迴
- 二叉樹遍歷方法總結二叉樹
- 資料結構——樹與二叉樹的遍歷資料結構二叉樹
- 二叉樹排序樹的建立,遍歷和刪除二叉樹排序
- 二叉樹的深度、寬度遍歷及平衡樹二叉樹
- 面試中很值得聊的二叉樹遍歷方法——Morris遍歷面試二叉樹
- 二叉樹的先中後序遍歷二叉樹
- 二叉樹的先,中,後序遍歷二叉樹
- 二叉樹的前中後序遍歷二叉樹
- Leetcode——144. 二叉樹的前序遍歷LeetCode二叉樹
- [LintCode]BinaryTreeLevelOrderTraversal(二叉樹的層次遍歷)二叉樹
- 根據前序遍歷序列、中序遍歷序列,重建二叉樹二叉樹
- 資料結構 二叉樹遍歷資料結構二叉樹