樹的三種遍歷方法程式碼實現 (資料結構)C語言
在此分別總結先序,中序,後序的結點輸出順序。
先序: 1.訪問根結點
2.訪問左子樹
3.訪問右子樹
中序:1.訪問左子樹
2.訪問根結點
3.訪問右子樹
訪問左子樹。【先訪問左子樹中的左子樹,再訪問左子樹中的右子樹。】直到訪問到葉子結點後輸出。
輸出根。
訪問右子樹。【先訪問右子樹中的左子樹,再訪問右子樹中的右子樹。】直到訪問到葉子結點後輸出。
後序:1.訪問左子樹
2.訪問右子樹
3.訪問根
訪問左子樹。【先訪問左子樹中的左子樹,再訪問左子樹中的右子樹】。直到訪問到葉子結點後輸出。
訪問右子樹。【先訪問右子樹中的左子樹,再訪問右子樹中的右子樹】。直到訪問到葉子結點後輸出。
再返回訪問根,並輸出。
如何用棧實現遞三種遍歷樹的演算法
1)前序遍歷
void preorder_nonrecursive(Bitree T) /* 先序遍歷二叉樹的非遞迴演算法 */
{
initstack(S);
push(S,T); /* 根指標進棧 */
while(!stackempty(S)) {
while(gettop(S,p)&&p) { /* 向左走到盡頭 */
visit(p); /* 每向前走一步都訪問當前結點 */
push(S,p->lchild);
}
pop(S,p);
if(!stackempty(S)) { /* 向右走一步 */
pop(S,p);
push(S,p->rchild);
}
}
}
2)中序遍歷
void inorder_nonrecursive(Bitree T)
{
initstack(S); /* 初始化棧 */
push(S, T); /* 根指標入棧 */
while (!stackempty(S)) {
while (gettop(S, p) && p) /* 向左走到盡頭 */
push(S, p->lchild);
pop(S, p); /* 空指標退棧 */
if (!stackempty(S)) {
pop(S, p);
visit(p); /* 訪問當前結點 */
push(S, p->rchild); /* 向右走一步 */
}
}
}
3)後序遍歷
typedef struct {
BTNode* ptr;
enum {0,1,2} mark;
} PMType; /* 有mark域的結點指標型別 */
void postorder_nonrecursive(BiTree T) /*
後續遍歷二叉樹的非遞迴演算法 */
{
EMType a;
initstack(S); /* S的元素為EMType型別 */
push (S,{T,0}); /* 根結點入棧 */
while(!stackempty(S)) {
pop(S,a);
switch(a.mark)
{
case 0:
push(S,{a.ptr,1}); /* 修改mark域 */
if(a.ptr->lchild)
push(S,{a.ptr->lchild,0}); /* 訪問左子樹 */
break;
case 1:
push(S,{a.ptr,2}); /* 修改mark域 */
if(a.ptr->rchild)
push(S,{a.ptr->rchild,0}); /* 訪問右子樹 */
break;
case 2:
visit(a.ptr); /* 訪問結點 */
}
}
}