樹的定義本是遞歸定義,因此採用遞歸的方法實現遍歷算法,更加讓人理解,且代碼簡單方便。若採用非遞歸的方法實現,須得利用棧模擬實現。
算法
棧的特色(後進先出)ide
非遞歸實現二叉樹的前序遍歷:
spa
原理如圖所示:
指針
參考代碼以下:blog
void _PrevOrder(Node* root)//非遞歸實現前序遍歷遞歸
{get
stack<Node*> s;it
if(root == NULL)io
return;class
s.push(root);
while (!s.empty())
{
root = s.top();
cout<<root->_data<<" ";
s.pop();
if (root->_right)
{
s.push(root->_right);
}
if(root->_left)
{
s.push(root->_left);
}
}
}
非遞歸實現二叉樹的中序遍歷
原理:
先從二叉樹的最左邊進行遍歷(一、二、3),且一邊遍歷,一邊入棧,噹噹到達結點3時,由於3的左右子樹都爲空,此時需彈出結點3,棧頂元素變爲2,再遍歷2的右子樹的左結點,由於4的左右子樹都爲空,此時需彈出2,壓人4,左子樹已遍歷結束,彈出4,再彈出1,依照遍歷左子樹,遍歷右子樹。
參考代碼以下:
void _InOrder(Node* root)//非遞歸實現中序遍歷
{
stack<Node*> s;
Node* cur = root;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
cout<<top->_data<<" ";
s.pop();
cur = top->_right;
}
}
非遞歸實現二叉樹的後序遍歷
步驟:
一、藉助棧實現後序遍歷,先找到最左邊且爲最下邊的結點3(一邊找,一邊入棧)
二、若3沒有右子樹,則彈出3且打印結點3,還須要引入一個指向當前彈出結點的指針prev
三、若3有右子樹,則須要遍歷右子樹,遍歷結束才能夠打印並彈出結點3,重複此三步驟可完成後序遍歷。
參考代碼以下:
void _PosOrder(Node* root)//非遞歸實現後序遍歷
{
Node* cur = root;
Node* prev = NULL;
stack<Node*> s;
if(root == NULL)
return;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
cur = s.top();
if(cur->_right == NULL || cur->_right == prev)
{
cout<<cur->_data<<" ";
s.pop();
prev = cur;
cur = NULL;
}
else
{
cur = cur->_right;
}
}
}