4-2-6 二叉树及其遍历 / 二叉搜索树 / 完全二叉树 完全二叉搜索树 (30 分)

一个无重复的非负整数序列,必定对应唯一的一棵形状为完全二叉树的二叉搜索树。本题就要求你输出这棵树的层序遍历序列。

输入格式:

首先第一行给出一个正整数 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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值