先序中序後序二叉樹非遞迴實現

2021-06-14 21:57:49 字數 1816 閱讀 8648

稍微解釋一下: 

先序遍歷。將根節點入棧,考察當前節點(即棧頂節點),先訪問當前節點,然後將其出棧(已經訪問過,不再需要保留),然後先將其右孩子入棧,再將其左孩子入棧(這個順序是為了讓左孩子位於右孩子上面,以便左孩子的訪問先於右孩子;當然如果某個孩子為空,就不用入棧了)。如果棧非空就重複上述過程直到棧空為止,結束演算法。 

中序遍歷。將根節點入棧,考察當前節點(即棧頂節點),如果其左孩子未被訪問過(有標記),則將其左孩子入棧,否則訪問當前節點並將其出棧,再將右孩子入棧。如果棧非空就重複上述過程直到棧空為止,結束演算法。 

後序遍歷。將根節點入棧,考察當前節點(即棧頂節點),如果其左孩子未被訪問過,則將其左孩子入棧,否則如果其右孩子未被訪問過,則將其右孩子入棧,如果都已經訪問過,則訪問其自身,並將其出棧。如果棧非空就重複上述過程直到棧空為止,結束演算法。 

其實,這只不過是保證了先序中序後序三種遍歷的定義。對於先序,保證任意乙個節點先於其左右孩子被訪問,還要保證其左孩子先於右孩子被訪問。對於中序,保證任意乙個節點,其左孩子先於它被訪問,右孩子晚於它被訪問。對於後序,保證任意乙個節點的左孩子右孩子都先於它被訪問,其中左孩子先於右孩子被訪問。如是而已。 

**裡應該體現得比較清楚。這裡不光給出了非遞迴版本,也給出了遞迴版本。

這裡需要強調一下:相對於教科書上實現方式,這種實現方式,visit和stack.pop總是結合在一起,這種非遞迴棧管理比較容易接受,而教科書上visit和pop可能是割裂的。最後會附上教科書上的實現方式。 

void preordernorecursion(treeptr p)  

} else

}

else if (stk.top().flag == 1)

}

else

if (!stackempty(s)) //通過下一次迴圈中的內嵌while實現右子樹遍歷

//endif

}//endwhile

}

2.中序遍歷非遞迴演算法

void inorderunrec(bitree *t)

if (!stackempty(s))

//endif

}//endwhile

}

3.後序遍歷非遞迴演算法

typedef enum tagtype;

typedef struct

stacknode;

typedef struct

sqstack;

void postorderunrec(bitree t)

while (!stackempty(s) && s.elem[s.top].tag==r)

if (!stackempty(s))

}while (!stackempty(s));

}//postorderunrec

我自己的實現:

#include #include using namespace std;

struct node

};void preorder(node* root)

if(tmp->l)

st.push(tmp->l);

}}void inorder(node* root)

else}}

}void postorder(node* root)

else

else}}

}

二叉樹非遞迴實現先序 中序 後序遍歷

測試資料 abc000de0f00g00 這是乙個先序序列 0表示當前結點為空 include includetypedef struct node node char chin 100 陣列從儲存獲取的二叉樹序列元素 int m int initchain node q,int step if q...

二叉樹先序 中序 後序 層序遍歷非遞迴實現

一 先序遍歷非遞迴實現 1.先建立乙個棧 2.把根節點放入棧中 3.迴圈取棧頂元素 4.訪問這個元素,並出棧 5.把當前元素的右子樹入棧 6.把當前元素的左子樹入棧 7.迴圈該過程 public static void preordernor treenode root 1.建立乙個棧 stacks...

二叉樹先序 中序 後序遍歷的非遞迴實現

在網上看了一些用非遞迴實現先序中序後序遍歷二叉樹的 都很混亂,while if各種組合巢狀使用,邏輯十分不清晰,把我也搞懵了。想了大半天,寫了大半天,突然開了竅,實際上二叉樹的這三種遍歷在邏輯上是十分清晰的,所以才可以用遞迴實現的那麼簡潔。既然邏輯如此清晰,那麼用非遞迴實現也應該是清晰的。自認為自己...