二叉樹遍歷的幾種方法算法
存儲結構:函數
typedef char ElemType; typedef struct BiTNode{ ElemType data; struct BiTNode *lchild,*rchild; }BiTNode;
遍歷spa
樹的遍歷順序是相對父結點來講的。3d
先序遍歷:指針
先訪問根結點,而後分別先序遍歷左子樹、右子樹。code
遞歸先序:blog
void PreOrderTraverse(BiTree bt) { /* 最簡單的Visit函數:Visit(ElemType e){printf(e);}*/ if(bt){ Visit(bt->data); PreOrderTraverse(bt->lchild); PreOrderTraverse(bt->rchild); } }
非遞歸先序:遞歸
1. p=根結點地址,初始化棧隊列
2. while(p!=NULL || 棧不空)it
while(p!=NULL ) 訪問p, p入棧, p=p->lchild
若棧不空,出棧p,p=p->rchild
void inorder_fdg(BiTNode *bt) /*非遞歸先序遍歷*/ { int top=0; BiTNode *p,*s[20]; p=bt; while(p!=NULL||top>0) { while(p!=NULL){ printf("%c ",p->data); // 先序遍歷 s[top++]=p; p=p->lchild; } if(top>0) { p=s[--top]; //printf("%c ",p->data); // 中序遍歷 p=p->rchild; } } }
中序遍歷:
先中序遍歷左子樹,而後訪問根結點,最後中序遍歷右子樹。
void InOrderTraverse(BiTree bt) { if(bt){ PreOrderTraverse(bt->lchild); Visit(bt->data); PreOrderTraverse(bt->rchild); } }
後序遍歷:
前後序遍歷左、右子樹,而後訪問根結點。
void InOrderTraverse(BiTree bt) { if(bt){ PreOrderTraverse(bt->lchild); PreOrderTraverse(bt->rchild); Visit(bt->data); } }
按層次遍歷:
從上到下、從左到右訪問各結點。
可以使用一個順序存儲的隊列q[100],存放尚未處理的子樹的根結點的地址。注意,隊首和隊尾指針分別指向隊首結點和下次進隊結點的存放位置。
void lev_traverse(BiTNode* T) { /* 用隊列實現層次遍歷 */ BiTNode *q[100],*p; int head,tail; q[0]=T;head=0;tail=1; while(head<tail) { /* 當隊列不空 */ p=q[head++]; printf("%c ",p->data); if(p->lchild!=NULL) q[tail++]=p->lchild; if(p->rchild!=NULL) q[tail++]=p->rchild; } }
其餘
先中後層的例子:
求二叉樹的深度(後序遍歷)
算法基本思想:
從二叉樹深度的定義可知,二叉樹的深度應爲其左、右子樹深度的最大值加1。
由此,需先分別求得左、右子樹的深度,算法中「訪問結點」的操做爲:求得左、右子樹深度的最大值,而後加 1 。
//計算二叉樹的深度 int Depth(BiTNode *bt) { int depth, depthLeft, depthRight; if (bt == NULL) depth = 0; else { depthLeft = Depth(bt->lchild); depthRight = Depth(bt->rchild); depth = 1 + (depthLeft > depthRight ? depthLeft : depthRight); } return depth; }