一个无重复的非负整数序列,必定对应唯一的一棵形状为完全二叉树的二叉搜索树。本题就要求你输出这棵树的层序遍历序列。
输入格式:
首先第一行给出一个正整数 N(≤1000),随后第二行给出 N 个不重复的非负整数。数字间以空格分隔,所有数字不超过 2000。
输出格式:
在一行中输出这棵树的层序遍历序列。数字间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
10
1 2 3 4 5 6 7 8 9 0
输出样例:
6 3 8 1 5 7 9 0 2 4
自己的思路
(差两个测试点,以后解决了再补充)
这个方法可能比较好想到,但是写起来挺麻烦的,可以直接跳过看下一种写法。
#include<iostream>
#include<algorithm>
using namespace std;
typedef struct tree* Tree;
struct tree {
int value;
Tree left;
Tree right;
};
struct queue
{
Tree Data;
struct queue* next;
};
struct queue* head = NULL , * tail = NULL;
Tree NewNode(Tree T,int n);
void Select(int fin[], Tree T, int start, int end);
Tree BuildTree(Tree T, int n);
void print(Tree T);//分层打印
void Pop(Tree T);
Tree Push();
int main()
{
int n,b,fin[1005];
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> fin[i];
}
sort(fin, fin + n);
int sum = 0,cen=1;//cen是每层最多节点个数
while (1) {
sum += cen;
if (sum >= n) break;
cen *= 2;
}
if (sum - n == 0)//正好最后一层铺满
sum = (sum + 1) / 2;//以根节点为中心左半部分节点个数(包括根节点
else
sum=(sum-cen+1)/2+cen-(sum-n);
sum--;
Tree T=NULL;
T=NewNode(T,fin[sum]);
if (sum != 0) {//这块的思路来源的想到之前写的通过中序和一个其他序重新构造二叉树
int start = 0, end = sum - 1;
Select(fin, T, start, end);
start = sum + 1, end = n - 1;
Select(fin, T, start, end);//建树完成,congratulations!
}
print(T);//通过层序遍历打印数据
}
void print(Tree T)
{
if (!T) return;
Tree point;
Pop(T);//入栈
while (head != NULL) {
if(head!=NULL)point=Push();//出栈
if (point->left) Pop(point->left);
if (point->right) Pop(point->right);
}
}
int flag = 0;
Tree Push()
{
Tree temp = head->Data;
head = head->next;
if (flag == 1) cout << " ";
flag = 1;
cout << temp->value;
return temp;
}
void Pop(Tree T)
{
struct queue*temp = (struct queue*)malloc(sizeof(struct queue));
temp->Data = T;
temp->next = NULL;//***一开始忘了,然后程序崩溃了
if (head == NULL) head = temp;
else tail->next = temp;
tail = temp;
}
Tree BuildTree(Tree T, int n)
{
if (!T) T = NewNode(T, n);
else {
if (n < T->value) T->left=BuildTree(T->left, n);
else T->right=BuildTree(T->right, n);
}
return T;
}
void Select(int fin[], Tree T, int start, int end)
{
int mid = (start + end+1) / 2;
T=BuildTree(T, fin[mid]);
if(start!=mid)Select(fin, T, start, mid-1);
if(mid!=end)Select(fin, T, mid+1, end);
}
Tree NewNode(Tree T, int n)
{
if (!T) T = (Tree)malloc(sizeof(struct tree));
T->value = n;
T->left = T->right = NULL;
return T;
}
参考代码(已AC):
#include<iostream>
#include<algorithm>
using namespace std;
int a[1005], t[1005];
int n,pos=1;
void BuildTree(int index);
int main()
{
cin >> n;
//从1开始记节点方便找父亲节点与子节点的关系 father*2===father*2+1===child
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + 1 + n);
//排序以后的a数组从1开始到n就是按照中序遍历排序的(这一点很重要,与下面的遍历有重大联系)
BuildTree(1);
for (int i = 1; i <= n; i++) {
cout << t[i];
if (i != n) cout << " ";
}
}
void BuildTree(int index)
{
if (index * 2 <= n) BuildTree(index * 2);
t[index] = a[pos++];
//当index==8时,对应本体测试数据构成的二叉树的最左边的节点,也是所有数据中最小的
//先到8,然后返回4,再到9,这个就是中序遍历,所以是按照这样的遍历方法将a里面的数据依次放入t数组(这个思路有点nubility!)
if (index * 2 + 1 <= n) BuildTree(index * 2 + 1);
}