本文記錄二叉樹的幾種遍歷方式,包括:前序,中序,後序三種遍歷方式的遞歸與非遞歸實現以及層次遍歷。
前序:根,左,右;
中序:左,根,右;
後序:左,右,根;
層次:按層從左到右。
/* define of binary tree
typedef struct Tree{
int value;
Tree *left, *right;
}*BinaryTree;
*/
1, 前序遍歷:
非遞歸實現:
typedef struct Node{
BinaryTree index;
int flag; //記錄棧中每個元素的狀態:0表示還未遍歷該節點的左子樹,1表示已經遍歷了左子樹。
};
void inorderTraversal(TreeNode *root) {
if(root == NULL) return;
stack<Node>st;
Node n;
n.pointer = root;
n.flag = 0;
st.push(n);
while(!st.empty())
{
Node top = st.top();
if(top.flag == 0)
{
st.top().flag = 1;
if(top.pointer->left != NULL)
{
Node tmp;
tmp.pointer = top.pointer->left;
tmp.flag = 0;
st.push(tmp);
}
}
else
{
st.pop();
cout<<top.pointer->value<<endl; //visit
if(top.pointer->right != NULL)
{
Node tmp;
tmp.pointer = top.pointer->right;
tmp.flag = 0;
st.push(tmp);
}
}
}
}
2, 中序遍歷:
3, 後序遍歷:
遞歸實現:
void postOrder(BinaryTree root)
{
if(root == NULL) return;
postOrder(root->left);
postOrder(root->right);
printf("%d ", root->value);
}
非遞歸實現:
typedef struct Node{
BinaryTree index;
int flag; //記錄棧中每個元素的狀態:0表示還未遍歷該節點的左右子樹,1表示已經遍歷了左子樹還未遍歷右子樹,2表示已經遍歷完了左右子樹。
};
void postorder_no_re(BinaryTree root)
{
if(root == NULL) return;
stack<Node>st;
Node tmp;
tmp.index = root;
tmp.flag = 0;
st.push(tmp);
while(!st.empty())
{
Node top = st.top();
if(top.flag == 2) //當左右子樹都已遍歷完成,現在就該遍歷當前節點
{
printf("%d ", top.index->value);
st.pop();
}
else if(top.flag == 0) //需要遍歷左子樹
{
st.top().flag = 1;
BinaryTree left = top.index->left;
if(left != NULL)
{
Node node;
node.index = left;
node.flag = 0;
st.push(node);
}
}
else // 遍歷右子樹
{
st.top().flag = 2;
BinaryTree right = top.index->right;
if(right != NULL)
{
Node node;
node.index = right;
node.flag = 0;
st.push(node);
}
}
}
}
4, 層次遍歷: