二叉樹遍歷的非遞迴演算法

2021-06-26 22:39:10 字數 2440 閱讀 1766

這裡主要講後序遍歷的非遞迴演算法,,在本文最後會給出整個測試**,包含先序 中序和後序的c++**^o^

其實後序遍歷演算法,其遞迴演算法很容實現, 但其非遞迴演算法有點煩人,我也是想了半個早上才想出來的= =

在看演算法之前,一定要銘記後序的定義:所謂後續就是在其左節點(左子樹) 和右節點(右子樹)訪問完之後,,才能訪問父節點。

我們可以將其演算法歸納為兩個操作:(1)堆疊操作 (2)回溯訪問操作

(注意,以下所說的「節點」和子樹等同,節點也可能是一棵樹)

(1)堆疊操作的原則:堆疊當然是按著先左後右的原則

1.先將父節點的左節點進行堆疊

2.若父節點的左節點為空,則對其右節點進行堆疊操作(因為後續遍歷對父節點訪問操作是在最後的, 所以儘管堆,左子節點沒有就往右子節點堆,直到遇到葉子節點)

3.迴圈上述1,2兩個操作,直到遇到葉子節點,則執行下面的回溯訪問操作(2)。

(2)回溯訪問操作的原則: 只有左右節點都訪問完才能訪問其父節點,若只訪問了左節點,還得訪問右節點

1.若訪問完當前節點,發現該節點是其父節點的左子節點,則接下來就要去訪問當前節點的右兄弟節點(因為當前是左節點說明右節點還沒訪問,不可以訪問父節點),跳往步驟4

2.若訪問完當前節點,發現該節點是其父節點的右子節點,則接先來就要去訪問其父節點(因為當前是右節點說明左右都訪問完了,就可以訪問父節點了)

3.若經歷步驟2發現,當前節點(也就是步驟2中的父節點)依然是其父節點的右子節點,則重複步驟2,直到找到乙個節點是其父節點的左子節點,則執行步驟1

4.經過步驟1,我們對當前節點(也就是步驟1中的右兄弟節點)進行堆疊操作(1)。

下面給出二叉樹後續遍歷的非遞迴演算法]

/***後序遍歷非遞迴演算法***/

void aforder(node * t)

//左節點為空,就對右節點堆疊,只有左右都訪問了才訪問父節點

else if (p->right != null)

else p = null;

} //接下來就是(2)回溯訪問操作

//p為空時,即左右節點都為空才訪問父節點(因為是後序),就會進入else

else

//經上面的回溯步驟後,找到乙個左節點,根據後序的定義,

//我們對其父節點的右子樹進行堆疊和訪問的操作

if (!stack.empty())

}//執行(1)(2)兩個操作一直到棧為空

} while (!stack.empty());

cout << endl;

}

接下來給出先序中序後序遍歷的非遞迴演算法的測試**,直接複製就可以執行了^o^,用c++寫的

這裡的棧當然採用c++的vector類來寫最方便了,**如下:

#include#includeusing namespace std;

struct node;

node* root;

node test[20];

/***構造具有11個節點的完全二叉樹***/

void init_tree()

for (int i = 6; i <= 11; i++)

}/***對節點的訪問操作***/

void visit(node* p)

/***棧的pop操作***/

void pop(vector& stack, node* &p)

/***棧的push操作***/

void push(vector& stack, node* &p)

/***獲取棧的最後乙個元素***/

void get_back(vector& stack, node* &p)

/***先序遍歷非遞迴演算法***/

void beorder(node* t)

else

} cout << endl;

}/***中序遍歷非遞迴演算法***/

void inorder(node* t)

else

} cout << endl;

}/***後序遍歷非遞迴演算法***/

void aforder(node * t)

//左節點為空,就對右節點堆疊,只有左右都訪問了才訪問父節點

else if (p->right != null)

else p = null;

} //p為空時,即左右節點都為空才訪問父節點(因為是後序),就會進入else

else

//經上面的回溯步驟後,找到乙個左節點,根據後序的定義,

//我們對其父節點的右子樹進行堆疊和訪問的操作

if (!stack.empty())

}//執行操作一直到棧為空

} while (!stack.empty());

cout << endl;}

/***主函式***/

int main()

二叉樹遍歷 非遞迴演算法

文庫文章 二叉樹前序遍歷 根 左結點 右結點 所以在訪問到乙個節點不為空時 先訪問此結點,然後把此結點的非空右孩子先入棧,然後再把非空左孩子入棧。具體 如下 二叉樹後序非遞迴演算法 第二種思路 要保證根結點在左孩子和右孩子訪問之後才能訪問,因此對於任一結點p,先將其入棧。如果p不存在左孩子和右孩子,...

二叉樹遍歷非遞迴演算法

輸入 include include define maxsize 100 typedef char elemtype using namespace std typedef struct node btnode 建立二叉樹 void createbtnode btnode b,char str j...

二叉樹遍歷非遞迴演算法

遞迴演算法非常的簡單。先訪問跟節點,然後訪問左節點,再訪問右節點。如果不用遞迴,那該怎麼做呢?仔細 一.先序遍歷 看一下遞迴程式,就會發現,其實每次都是走樹的左分支 left 直到左子樹為空,然後開始從遞迴的最深處返回,然後開始恢復遞迴現場,訪問右子樹。由於一直走到最左邊後,需要逐步返回到父節點訪問...