2012-06-02 22:33 21362人閱讀 評論(5) 收藏 舉報 node
分類: ios
筆試面試(30) 面試
做者同類文章X算法
版權聲明:本文爲博主原創文章,未經博主容許不得轉載。編程
給定一棵二叉樹,要求按分層遍歷該二叉樹,即從上到下按層次訪問該二叉樹(每一層將單獨輸出一行),每一層要求訪問的順序爲從左到右,並將節點依次編號。下面是一個例子:網絡
輸出:ide
1 2 3 4 5 6 7 8
節點的定義:post
[cpp] view plain copy print?spa
structNode {
Node *pLeft;
Node *pRight;
intdata;
};
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?
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());
}
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?
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
struct Node
{
Node *pLeft;
Node *pRight;
int data;
};
void Link(Node *nodes, int parent, int left, int right);
void PrintNodeByLevel(Node *root);
int main(int argc, char* argv[])
{
Node test1[9] = {0};
int i;
for (i = 0; i < 9; i++)
{
test1[i].data = i;
}
Link(test1, 1, 2, 3);
Link(test1, 2, 4, 5);
Link(test1, 3, -1, 6);
Link(test1, 5, 7, 8);
PrintNodeByLevel(&test1[1]);
return 0;
}
void Link(Node *nodes, int parent, int left, int right)
{
if (left != -1)
{
nodes[parent].pLeft = &nodes[left];
}
if (right != -1)
{
nodes[parent].pRight = &nodes[right];
}
}
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());
}