二叉树的层次遍历

   

       [编程之美]二叉树的层次遍历                                                  

           标签:               编程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. }