本篇文章主要詳解利用棧的方式二叉樹先序、中序、後序遍歷的非遞迴寫法
首先我們需要實現一顆二叉樹。
以下是通過先序序列建樹的**
例如:先序序列代表以下的樹
//引數型別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...