LeetCode | Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).

For example:
Given binary tree {3,9,20,#,#,15,7},

    3
   / \
  9  20
    /  \
   15   7

return its level order traversal as:

[
  [3],
  [9,20],
  [15,7]
]

思路:本題需要按層從左到右輸出每層的結點值,放在一個二維數組中。那麼首先可以用二叉樹的廣度優先算法,將結點按按層排序好,放在一個一維數組中,問題是如何知道數組中的每個點分別是在第幾層?

這邊需要注意的是,在用廣度優先算法的時候,我是將空結點也放進了數組中。即若某結點p的左子樹如果爲空,則也將指向這顆空子樹的指針也放進數組中。

下面來看如何知道數組中每個結點分別是二叉樹第幾層的結點。

很顯然,第一層的結點即是數組中的第一個結點,記爲v[0],那麼第二層的結點,就是v[1],v[2],第三層就是v[3],v[4],v[5],v[6]。以此類推。

真的就是這麼簡單,顯然不是。上面的這種情況二叉樹是滿二叉樹(即每層結點都是滿的),所以如果不是滿二叉樹,那麼又該如何來做呢?

做法就是在遍歷每一層的每一個結點時,我們可以記一個數cnt,如果該結點存在,就把cnt = cnt + 2;否則就不需要加2。這樣的做法,就可以知道實際的下一層一共有多少個結點。因此,一旦我們知道了下一層的結點總數 (即每一層的結點總數),就可以從數組中容易地區分每個結點在第幾層。

我想大致思路應該是講清楚了。

#include "stdafx.h"
#include <vector>
#include <queue>
#include <iostream>
using namespace std;

  struct TreeNode 
  {
     int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  };
 
class Solution {
public:
    vector<vector<int> > levelOrder(TreeNode *root) 
	{
		vector<vector<int> > vv;//最終的結果,一個二維向量(數組)
		vector<int> v;<span style="white-space:pre">		</span>//一個存放每層結點元素值的臨時向量(不包括空結點)
		vector<TreeNode*> vt;<span style="white-space:pre">	</span>//這個向量存放到即是每層的結點(包括空結點)
		queue<TreeNode*> L;<span style="white-space:pre">	</span>//廣度優先時,用到的輔助隊列
		TreeNode* t;
		int i,j;
		if(root)<span style="white-space:pre">		</span>//廣度優先
		{
			v.push_back(root->val); 
			vv.push_back(v); //這邊直接將第一層的結點元素值,放進最終結果了
		}
		L.push(root);
		while(!L.empty())
		{
			t = L.front();
			vt.push_back(t);
			L.pop();
			if(!t)
				continue;
			L.push(t->left);
			L.push(t->right);
		}
		int step = 3;
		int cnt = 0;
		for(i=1; i<vt.size(); i=j)//從第二層開始
		{
			v.clear();<span style="white-space:pre">	</span>//清空<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">存放每層結點元素值的臨時向量</span>
			for(j=i; j<vt.size() && j<step; ++j)
			{
				if(vt[j])//不是空結點,則將結點元素值放入臨時向量中,並將計數值+2
				{
					v.push_back(vt[j]->val);
					cnt+=2;
				}
			}
			step = j+cnt;//下一層的實際結點樹
			cnt = 0;<span style="white-space:pre">	</span>//計數值清零
			if(!v.empty())
				vv.push_back(v);//每一層實際結點元素值,放入最終結果向量中
		}
		return vv;
    }
};


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