1. 程式人生 > >C++:二叉查詢樹實現(二)——遍歷操作

C++:二叉查詢樹實現(二)——遍歷操作

     建立好二叉樹,有時候我們需要對整個二叉樹錦星遍歷,即輸出二叉樹的所有結點元素。理論上,遍歷的方式有無數種,順序可以自己任意選定,但是絕大部分遍歷方式在實際中並沒有用處,比較有用的的遍歷方式有兩種:廣度優先遍歷、深度優先遍歷。

(1)廣度優先遍歷

        廣度優先遍歷的意思是每次優先遍歷完一層的所有子節點,遍歷完N層子節點後再遍歷N+1層節點,遵循的原則是自上而下、自左向右。

                                                                       

                                                                                   圖1.典型二叉查詢樹

     圖中的二叉查詢樹使用廣度優先遍歷的方法,獲得的結果是:8,3,10,1,6,14,4,7,13.。

     要實現廣度優先遍歷,可以考慮使用佇列實現,我們知道佇列的性質是先進先出,我們先將節點8壓入佇列,輸出節點後,彈出節點8,再將節點3和節點10壓入佇列(注意順序)。接下來繼續對佇列處理,節點3先壓入佇列,所以先處理節點3,處理完之後將該節點彈出,將其左有兩個節點1和6壓入佇列,但是要注意此時佇列中還有節點10沒有處理,因此先處理節點10,處理完之後彈出並將其子節點14壓入佇列。以此類推,二叉樹的節點壓入佇列的順序為

                                                                          圖2.廣度優先遍歷時節點入隊順序以及輸出順序

         圖中的豎線表示這些節點是在不同的迴圈中壓入佇列,按這個順序對二叉樹輸出,,圖中相同顏色曲線表示這些節點在相同層輸出的,這樣就能完成廣度優先遍歷,程式如下:

void Btree::BreadthFirstVisit()
{
	BreadthFirstVisit(root);

}
void Btree::BreadthFirstVisit(BtreeNode *Bvs)
{
	queue<BtreeNode *> nodeQueue;
	nodeQueue.push(root);
	
	while (!nodeQueue.empty())
	{
		BtreeNode *node = nodeQueue.front();
		cout << node->ele << ' ';
		nodeQueue.pop();
		if (node->left)
			nodeQueue.push(node->left);
		if (node->right)
			nodeQueue.push(node->right);
	}

(1)深度優先遍歷

     深度優先遍歷就是優先遍歷完某一條線的所有子節點,遍歷完之後再考慮下一條線,所遵循的順序仍然是自上而下,自左向右。圖1的二叉樹,如果採用深度優先遍歷原則,輸出的順序為8 3 1 6 4 7 10 14 13。

   類似廣度優先遍歷,我們可以考慮用棧實現深度優先遍歷,將節點一次壓入棧,注意棧的原則是後進先出。我們首先將8壓入棧,此時棧中只有8一個元素,輸出並彈出,然後將其右節點10和左結點3分別壓入棧,注意是先壓右再壓左,這樣才能保證左邊的先輸出。接著輸出節點3並彈出節點,彈出後將節點3的右節點6和左結點1分別壓入棧,注意此時節點1是最後入棧的,因此需要先處理節點1,處理完節點1之後,因為節點1沒有子節點了,再來處理節點6,處理完節點6後還有其左節點4和右節點7,這兩個節點肯定是後入棧的,所以必然會先處理,將這些處理完之後,再回去處理節點10。以此類推。所有節點入棧的順序為

                          

                                                                 圖3.  深度優先遍歷法節點入棧順序以及輸出順序

      圖3顯示了採用深度優先遍歷是節點入棧順序,豎線同樣表示節點是在不同迴圈壓入棧的,兩種不同顏色的路線表示其中一條完成後才會進行另一條輸出,紅色代表節點8的左結點產生的分支,綠色部分表示節點8右節點產生的分支。深度優先遍歷的程式如下

void Btree::DepthFirstVisit(BtreeNode* dvs)
{
	stack<BtreeNode*> nodeStack;
	nodeStack.push(root);
	while (!nodeStack.empty())
	{
		BtreeNode *node = nodeStack.top();
		cout << node->ele << ' ';
		nodeStack.pop();
		if (node->right)
		{
			nodeStack.push(node->right);
		}
		if (node->left)
		{
		
			nodeStack.push(node->left);
		}
     }

}