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

2021-08-18 11:16:58 字數 2420 閱讀 2306

本篇文章主要詳解利用棧的方式二叉樹先序、中序、後序遍歷的非遞迴寫法

首先我們需要實現一顆二叉樹。

以下是通過先序序列建樹的**

例如:先序序列代表以下的樹

//引數型別arr 陣列指標,index 下標,size 陣列元素個數,invalid代表先序遍歷時遇到的null
pnode createtree_prevorder( const int* arr, size_t& index,const size_t size,int invalid)return root;}

先序非遞迴:

先序遍歷時,每當我們壓入乙個結點,我們壓入結點前對其進行訪問。

void prevorder_nr(pnode root)

cur = s.top(); //此時cur為空,因此需要對cur進行處理

s.pop(); //將棧頂結點的右子樹結點壓入棧前,將棧頂結點彈出,避免死迴圈

cur = cur->_right;//在下乙個while時將右子樹結點壓入棧

} cout << "over"中序非遞迴:

中序時我們需要在遍歷完左子樹後訪問根節點,再去遍歷右子樹,因此我們僅需依照先序遍歷修改部分**。

void inorder_nr(pnode root)

cur = s.top();//取棧頂結點

cout << cur->_data << "->" ;//訪問左結點,此時棧頂節點有兩種情況:1.左子樹結點為空;2.左子樹結點已被訪問彈出

s.pop(); //彈出訪問過的結點

cur = cur->_right; //將棧頂結點的右子樹結點入棧

} cout << "over" << endl;

}

後序遍歷:

後序遍歷時由於訪問完左右子樹後才能訪問根結點,因此需要將根結點在棧內保留到左右子樹被訪問後,但同時會出現乙個問題,當右子樹彈出後遇到根結點又會將右子樹結點壓入棧中,造成死迴圈,因此我們需要在定義乙個變數last代表最後乙個訪問的結點,當last與棧頂結點的右子樹結點相同時,則不再將右子樹結點壓入棧中。

void pastorder_nr(pnode root)

cur = s.top();

if (cur->_right && last != cur->_right)//考慮棧頂結點的右子樹結點。存在且沒被訪問過,將右子樹結點壓入棧中

else if ((null == cur->_right) || (last == cur->_right))

//右子樹結點為空或者已經被訪問過,則訪問棧頂結點並彈出

}cout << "over" << endl;

}

附帶遞迴寫法用於測試正確性

void prevorder(pnode root)

void pastorder(pnode root)

void inorder(pnode root)

void test()

; size_t index = 0;

pnode root=createtree_prevorder(arr, index, sizeof(arr)/sizeof(arr[0]), '#');

cout << "prevorder_nr:" ;

prevorder_nr(root);

cout << "prevorder :";

prevorder(root);

cout << endl;

cout << "inorder_nr:";

inorder_nr(root);

cout << "inorder :";

inorder(root);

cout << endl;

cout << "pastorder_nr:";

pastorder_nr(root);

cout << "pastorder :";

pastorder(root);

cout << endl;

}

測試結果:

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

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

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

測試資料 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...