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());
}