3.10分層遍歷二叉樹-擴展問題

1.問題定義

       給定一棵二叉樹,要求按分層遍歷該二叉樹,即從上到下按層次訪問該二叉樹(每一層將單獨輸出一行),每一層要求訪問的順序爲從左到右,並將節點依次編號。 要求遍歷輸出的結果分別爲圖2,圖3和圖4,其中圖3和圖4是擴展問題。

                 

                       圖1                                           圖2                               圖3                                     圖4

 

2.原問題

        編程之美書上,採用的是容器構成的數組來實現的,相比於遞歸算法,時間複雜度大大降低,僅爲O(n),但其空間複雜度並非最優。此處採用STL中的Queue來解決此問題,代碼如下:

節點數據:

struct node
{
	char value;
	node* pleft;
	node* pright;
};

實現代碼:

queue<node*> Queue3;//------------------使用系統的STL的queue
void cengxu3(node* root)
{
	node *temp;
	Queue3.push(root);
	int len=Queue3.size();
	int cur=0;
	while(!Queue3.empty())
	{
		while(cur++<len)//cur++,注意一些小的邏輯
		{
			temp=Queue3.front();
			Queue3.pop();
			cout<<temp->value<<" ";
			if (temp->pleft)
			   Queue3.push(temp->pleft);
			if (temp->pright)
			   Queue3.push(temp->pright);
		}
		cout<<endl;
		cur=0;
		len=Queue3.size();
	}
}

分析總結:

        該法中採用隊列,將已輸出的節點彈出,節省了空間開銷,降低了空間複雜度。

         對於輸出指定行的節點數據,只需引入一個變量保存層數即可,代碼如下:

queue<node*> Queue5;
void cengxu_n_ceng(node *root,int ceng)
{
	int cur=0,len=1,cengshu=0;
	Queue5.push(root);
	while(!Queue5.empty())
	{
		while(cur++<len)
		{
			node *temp=Queue5.front();
			Queue5.pop();
			if (cengshu==ceng)
			{
			   cout<<temp->value<<" ";
			}
			if (temp->pleft)
			  Queue5.push(temp->pleft);
			if (temp->pright)
                          Queue5.push(temp->pright);
		}
		if (cengshu==ceng)
		{
                    cout<<endl;
		    return;
		}
		else
		cengshu++;
		cur=0;
		len=Queue5.size();
	}
}

 

3.擴展問題

        圖3中的輸出順序剛好是圖1中的逆序,先壓人棧中,再出棧即可。圖4中,每一行的輸出順序和原問題的順序相同,可壓人隊列存儲,行序和原問題相反,可將每一行作爲隊列壓入棧中。再出棧、出隊列輸出即可。方便起見,將原問題和擴展圖3和圖4的擴展問題的代碼,編寫在一起,如下:

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <string>
#include <queue>
#include <vector>
#include <stack>
using namespace std;
struct node
{
	char value;
	node* pleft;
	node* pright;
};
queue<node*> Queue3;//------------------使用系統的STL的queue
stack<int> Queue3_temp;
stack<queue<node*>> Queue3_tempfan;
void cengxu3(node* root)
{
	node *temp;
	queue<node*> Queue3_fuzhu;
	char temp_value;
	Queue3.push(root);
	Queue3_tempfan.push(Queue3);
	int len=Queue3.size();
	int cur=0;
	while(!Queue3.empty())
	{
		while(cur++<len)//cur++,注意一些小的邏輯、圖2的結果
		{
			temp=Queue3.front();
			Queue3_temp.push(temp->value);
			Queue3.pop();
			cout<<temp->value<<" ";
			if (temp->pleft)
			{
				Queue3.push(temp->pleft);
			}
			if (temp->pright)
			{
				Queue3.push(temp->pright);
			}
		}
		Queue3_tempfan.push(Queue3);
		Queue3_temp.push('\n');
		cout<<endl;
		cur=0;
		len=Queue3.size();
	}
	while(!Queue3_temp.empty())//圖3的結果
	{
		temp_value=Queue3_temp.top();
		Queue3_temp.pop();
		if (temp_value=='\n')
		{
                  cout<<temp_value;
		}
		else
                  cout<<temp_value<<" ";
	}

	while(!Queue3_tempfan.empty())//圖4的結果
	{
		Queue3_fuzhu=Queue3_tempfan.top();//注意要彈出
		Queue3_tempfan.pop();
		while(!Queue3_fuzhu.empty())
		{
			temp=Queue3_fuzhu.front();
			Queue3_fuzhu.pop();
			cout<<temp->value<<" ";
		}
		cout<<endl;		
	}
}

4.測試結果

        採用先序和中序結果重建二叉樹(代碼見3.9),再對其進行遍歷的測試結果如圖5所示,前四行分別爲先序、中序、後序和層序遍歷結果,後面3個三角形分別對應圖2、圖3、圖4中的結果。

  

                              圖5

歡迎各位交流批評指正^_^····

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章