對於任一結點p:
1)訪問結點p,並將結點p入棧;
2)判斷結點p的左孩子是否為空,若為空,則取棧頂結點並進行出棧操作,並將棧頂結點的右孩子置為當前的結點p,迴圈至1);
若不為空,則將p的左孩子置為當前的結點p;
3)直到p為null並且棧為空,則遍歷結束。
//非遞迴先序遍歷
void preorder2(node *root)
if (!stk.empty())
}}
對於任一結點p,
1)若其左孩子不為空,則將p入棧並將p的左孩子置為當前的p,然後對當前結點p再進行相同的處理;
2)若其左孩子為空,則取棧頂元素並進行出棧操作,訪問該棧頂結點,然後將當前的p置為棧頂結點的右孩子;
3)直到p為null並且棧為空則遍歷結束
//非遞迴中序遍歷
void inorder2(node* root)
if (!stk.empty())
}}
後序遍歷的非遞迴實現是三種遍歷方式中最難的一種。因為在後序遍歷中,要保證左孩子和右孩子都已被訪問並且左孩子在右孩子前訪問才能訪問根結點。
對於任一結點p,將其入棧,然後沿其左子樹一直往下搜尋,直到搜尋到沒有左孩子的結點,此時該結點出現在棧頂,但是此時不能將其出棧並訪問,因此其右孩子還為被訪問。
所以接下來按照相同的規則對其右子樹進行相同的處理,當訪問完其右孩子時,該結點又出現在棧頂,此時可以將其出棧並訪問。這樣就保證了正確的訪問順序。
可以看出,在這個過程中,每個結點都兩次出現在棧頂,只有在第二次出現在棧頂時,才能訪問它。因此需要多設定乙個變數標識該結點是否是第一次出現在棧頂。
void postorder2(node* root)
if (!stk.empty())
else}}
}
#include
#include
#include
#include
using
namespace
std;
struct node
};struct tmpnode
};node* builttreehelper(istringstream& is)
node *u = new node(atoi(str.c_str()));
u->left = builttreehelper(is);
u->right = builttreehelper(is);
return u;
}node* builttree(string str)
void preorder(node *root)
if (root->left)
preorder(root->left);
if (root->right)
preorder(root->right);
}//非遞迴先序遍歷
void preorder2(node *root)
if (!stk.empty())
}}//非遞迴中序遍歷
void inorder2(node* root)
if (!stk.empty())
}}void postorder2(node* root)
if (!stk.empty())
else}}
}int main()
參考 二叉樹遍歷(遞迴 非遞迴)
二叉樹以及對二叉樹的三種遍歷 先根,中根,後根 的遞迴遍歷演算法實現,以及先根遍歷的非遞迴實現。node public class node public node left public node right public object value 遍歷訪問操作介面 public inte ce ...
二叉樹非遞迴遍歷
二叉樹非遞迴遍歷的幾個要點 1 不管前序 中序還是後序,它們的遍歷路線 或者說是回溯路線,先沿左邊一直走到盡頭,然後回溯到某節點,並跳轉到該節點的右孩子 如果有的話 然後又沿著這個有孩子的左邊一直走到盡頭 都是一樣的。2 明確每次回溯的目的。比如,前序回溯的目的是為了訪問右子樹 中序回溯的目的是為了...
非遞迴遍歷二叉樹
中序遞迴遍歷 void inordertrvdigui node pnode 然而,當樹的深度很大 比如16 時 假設為滿二叉樹 樹的節點數為 2 0 2 1 2 2 2 15 2 16 65536,遍歷整個二叉樹意味著有65536次函式呼叫,這將極大地增加程式執行時間。這時,應該採取非遞迴便利二叉...