二叉樹的層次遍歷

   

       [編程之美]二叉樹的層次遍歷                                                  

           標籤:               編程nullvector算法tree存儲                    html

            21362人閱讀             評論(5)             收藏              舉報        node

category_icon.jpg             分類:        ios

筆試面試(30)                       arrow_triangle%20_down.jpg                       arrow_triangle_up.jpg                        面試

做者同類文章X算法

問題定義

給定一棵二叉樹,要求按分層遍歷該二叉樹,即從上到下按層次訪問該二叉樹(每一層將單獨輸出一行),每一層要求訪問的順序爲從左到右,並將節點依次編號。下面是一個例子:網絡

輸出:ide

1
2 3
4 5 6
7 8

節點的定義:post

[cpp] view plain copy print?spa

  1. structNode {  

  2.     Node *pLeft;  

  3.     Node *pRight;  

  4.     intdata;  

  5. };  

structNode {
    Node *pLeft;
    Node *pRight;
    intdata;
};



《編程之美》書上提供了兩種解法,能夠參考http://www.cnblogs.com/miloyip/archive/2010/05/12/binary_tree_traversal.html 我的以爲編程之美對這個題目的分析不是很讓人滿意,這題有個簡單而又有效的算法,就是圖的廣度優先搜索,那麼咱們須要用到一個隊列,《編程之美》用到了一個vector,而後再用兩個遊標,實在是不直觀,且浪費存儲空間,若是用隊列,則空間複雜度能夠下降一半O(N/2)。


該題的一個小難點就在於要分層輸出,若是不須要分層的話,則一個普通的廣度優先模板就能夠解決這個問題了,書中最後提到了葉勁峯編寫的一個算法,其主要特色是在隊列中每一層節點以後插入一個傀儡節點,當咱們到達一個傀儡節點時,就知道咱們已經遍歷了一層,要開始新的一層,這時候須要換行了。


基於獨立思考,我想到了一個差很少的方法,可能實現上更簡單一點(我相信網絡上早已有人想到了,不過我本身想到的,是我本身的收穫,特記錄之)咱們能夠在遍歷當前層的時候,保存下一層的節點數,只須要每次插入一個節點的時候childSize++便可,這樣咱們就知道下一層有幾個節點了,而後將childSize賦值給parentSize,開始新的一層遍歷,從隊列中取出parentSize個節點之後,也就知道這一層遍歷完了。


因爲這是二叉樹,因此一開始的時候parentSize = 1, childSize = 0。

核心代碼以下:

[cpp] view plain copy print?

  1. void PrintNodeByLevel(Node *root)  

  2. {  

  3.     int parentSize = 1, childSize = 0;  

  4.     Node * temp;  

  5.     queue<Node *> q;  

  6.     q.push(root);  

  7.     do  

  8.     {  

  9.         temp = q.front();         

  10.         cout << temp->data << "  ";  

  11.         q.pop();  

  12.   

  13.         if (temp->pLeft != NULL)   

  14.         {  

  15.             q.push(temp->pLeft);  

  16.             childSize ++;  

  17.         }  

  18.         if (temp->pRight != NULL)   

  19.         {  

  20.             q.push(temp->pRight);  

  21.             childSize ++;  

  22.         }  

  23.   

  24.         parentSize--;  

  25.         if (parentSize == 0)   

  26.         {  

  27.             parentSize = childSize;  

  28.             childSize = 0;  

  29.             cout << endl;  

  30.         }  

  31.   

  32.     } while (!q.empty());  

  33. }  

void PrintNodeByLevel(Node *root)
{
	int parentSize = 1, childSize = 0;
	Node * temp;
	queue<Node *> q;
	q.push(root);
	do
	{
		temp = q.front();		
		cout << temp->data << "  ";
		q.pop();

		if (temp->pLeft != NULL) 
		{
			q.push(temp->pLeft);
			childSize ++;
		}
		if (temp->pRight != NULL) 
		{
			q.push(temp->pRight);
			childSize ++;
		}

		parentSize--;
		if (parentSize == 0) 
		{
			parentSize = childSize;
			childSize = 0;
			cout << endl;
		}

	} while (!q.empty());
}


完整代碼以下:

[cpp] view plain copy print?

  1. #include <iostream>  

  2. #include <queue>  

  3. #include <algorithm>  

  4. using namespace std;  

  5.   

  6. struct Node  

  7. {  

  8.     Node *pLeft;  

  9.     Node *pRight;  

  10.     int data;  

  11. };  

  12.   

  13. void Link(Node *nodes, int parent, int left, int right);  

  14. void PrintNodeByLevel(Node *root);  

  15.   

  16. int main(int argc, char* argv[])  

  17. {  

  18.     Node test1[9] = {0};  

  19.     int i;  

  20.   

  21.     for (i = 0; i < 9; i++)   

  22.     {  

  23.         test1[i].data = i;  

  24.     }  

  25.   

  26.     Link(test1, 1, 2, 3);  

  27.     Link(test1, 2, 4, 5);  

  28.     Link(test1, 3, -1, 6);  

  29.     Link(test1, 5, 7, 8);  

  30.   

  31.     PrintNodeByLevel(&test1[1]);  

  32.   

  33.     return 0;  

  34. }  

  35.   

  36. void Link(Node *nodes, int parent, int left, int right)  

  37. {  

  38.     if (left != -1)   

  39.     {  

  40.         nodes[parent].pLeft = &nodes[left];  

  41.     }  

  42.     if (right != -1)   

  43.     {  

  44.         nodes[parent].pRight = &nodes[right];  

  45.     }  

  46. }  

  47.   

  48. void PrintNodeByLevel(Node *root)  

  49. {  

  50.     int parentSize = 1, childSize = 0;  

  51.     Node * temp;  

  52.     queue<Node *> q;  

  53.     q.push(root);  

  54.     do  

  55.     {  

  56.         temp = q.front();         

  57.         cout << temp->data << "  ";  

  58.         q.pop();  

  59.   

  60.         if (temp->pLeft != NULL)   

  61.         {  

  62.             q.push(temp->pLeft);  

  63.             childSize ++;  

  64.         }  

  65.         if (temp->pRight != NULL)   

  66.         {  

  67.             q.push(temp->pRight);  

  68.             childSize ++;  

  69.         }  

  70.   

  71.         parentSize--;  

  72.         if (parentSize == 0)   

  73.         {  

  74.             parentSize = childSize;  

  75.             childSize = 0;  

  76.             cout << endl;  

  77.         }  

  78.   

  79.     } while (!q.empty());  

  80. }  

相關文章
相關標籤/搜索