1064. Complete Binary Search Tree (30)

时间限制
100 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
  • Both the left and right subtrees must also be binary search trees.

A Complete Binary Tree (CBT) is a tree that is completely filled, with the possible exception of the bottom level, which is filled from left to right.

Now given a sequence of distinct non-negative integer keys, a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=1000). Then N distinct non-negative integer keys are given in the next line. All the numbers in a line are separated by a space and are no greater than 2000.

Output Specification:

For each test case, print in one line the level order traversal sequence of the corresponding complete binary search tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

Sample Input:

10
1 2 3 4 5 6 7 8 9 0

Sample Output:

6 3 8 1 5 7 9 0 2 4

  这道题考察的点是二叉搜索树和完全二叉树。刚开始我第一反应就是完全二叉树的性质:用数组存储的话,父节点下标为i,左孩子为2i,右孩子为2i+1。而一个完全二叉搜索树的最小节点肯定在最左边。我一开始的想法是用数组存储,找到最左边那个位置,放进去0,然后找到0的父节点,放1,再放右节点的2,再往上一直放,但是当时没想到用递归,觉得这样写会很麻烦,所以放弃了。
接着我用了最普通的链式方法建树,然后层序遍历输出。不得不说,链式方法建树很繁琐,我调试了很久才通过。具体思路是,先把输入数据放在一个vector里面,然后排序,从小到大排。然后找出整个树的根节点的下标(找的方法是先计算左子树有几个节点),再递归,在左子树再建树。这样非常麻烦,写递归的时候很容易出错。
后来AC之后在网上搜了搜,发现有非常好的做法。其实我一开始的想法类似,但是没有更进一步去想。一个完全二叉搜索树的中序遍历的结果就是递增排列的,那么我们采用中序遍历的方法去建树(即遍历的时候,visit操作是给节点赋值!)。这种逆向思维是我之前完全没想到的,这次学习了。总之就是,采用中序遍历的方法,利用完全二叉树的父子节点关系去建树,最后把数组按序输出即可。
下面我把两种方法的代码都贴上来。很明显,第一段代码明显比第二段简单得多得多得多得多!!!
 #include<iostream>
#include<vector>
#include<algorithm>
using namespace std; int N;
int pos=;
int *tree;
vector<int> vec; void build(int n)
{
if (n>N) return;
else
{
build(n*);
tree[n] = vec[pos++];
build(n*+);
}
} int main()
{
int element;
cin >> N;
tree = new int [N+];
//输入元素并排序
for (int i=;i<N;i++)
{
cin >> element;
vec.push_back(element);
}
sort(vec.begin(),vec.end()); build();
cout << tree[];
for (int i=;i<=N;i++)
cout << ' ' << tree[i];
return ;
}
 #include<iostream>
#include<vector>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std; typedef struct node* tree;
struct node
{
int data;
tree left;
tree right;
}; tree BuildTree (tree,int,unsigned,unsigned);
int FindRoot(int,int);
void LevelOrderTraversal(tree T);
vector<int> vec; int main()
{
int N,element;
cin >> N; //输入元素并排序
for (int i=;i<N;i++)
{
cin >> element;
vec.push_back(element);
}
sort(vec.begin(),vec.end()); unsigned b=,e=vec.size()-; int root=FindRoot(N,);
tree T = nullptr;
T=BuildTree(T,root,b,e); LevelOrderTraversal(T); return ;
} int FindRoot(int N,int base)
{
int level=int(log(double(N))/log(2.0))+; //共有这么多层
int root=;
if (N == )
root = ;
else if (N == )
root = ;
else if (N==)
root = ;
else
if (N-(pow(double(),double(level-))-) > pow(double(),double(level-)) )//左子树满了
root = pow(double(),double(level-))-;
else
root = pow(double(),double(level-))-+N-(pow(double(),double(level-))-);
return root+base;
} tree BuildTree(tree T,int root,unsigned b,unsigned e)
{
//cout << b << e << endl;
if (e==b)
{
T=new node;
T->data = vec[b];
T->left = nullptr;
T->right = nullptr;
}
else
{
T = new node;
T->data = vec[root];
T->left = BuildTree(T,FindRoot(root-b,b),b,root-);
if (e!=root)
T->right= BuildTree(T,FindRoot(e-root,root+),root+,e);
else
T->right = nullptr;
}
return T;
} void LevelOrderTraversal(tree T)
{
bool flag=true;
queue<tree> Q;
if (!T) return;
Q.push(T);
while (!Q.empty())
{
if (flag)
{
cout << Q.front()->data;
flag = false;
}
else
cout << ' ' << Q.front()->data;
if (Q.front()->left)
Q.push(Q.front()->left);
if (Q.front()->right)
Q.push(Q.front()->right);
Q.pop();
}
}
 

PAT题库-1064. Complete Binary Search Tree (30)的更多相关文章

  1. PAT甲级:1064 Complete Binary Search Tree (30分)

    PAT甲级:1064 Complete Binary Search Tree (30分) 题干 A Binary Search Tree (BST) is recursively defined as ...

  2. PAT甲题题解-1064. Complete Binary Search Tree (30)-中序和层次遍历,水

    由于是满二叉树,用数组既可以表示父节点是i,则左孩子是2*i,右孩子是2*i+1另外根据二分搜索树的性质,中序遍历恰好是从小到大排序因此先中序遍历填充节点对应的值,然后再层次遍历输出即可. 又是一道遍 ...

  3. 【PAT甲级】1064 Complete Binary Search Tree (30 分)

    题意:输入一个正整数N(<=1000),接着输入N个非负整数(<=2000),输出完全二叉树的层次遍历. AAAAAccepted code: #define HAVE_STRUCT_TI ...

  4. PAT (Advanced Level) 1064. Complete Binary Search Tree (30)

    因为是要构造完全二叉树,所以树的形状已经确定了. 因此只要递归确定每个节点是多少即可. #include<cstdio> #include<cstring> #include& ...

  5. pat 甲级 1064. Complete Binary Search Tree (30)

    1064. Complete Binary Search Tree (30) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHE ...

  6. 1064. Complete Binary Search Tree (30)【二叉树】——PAT (Advanced Level) Practise

    题目信息 1064. Complete Binary Search Tree (30) 时间限制100 ms 内存限制65536 kB 代码长度限制16000 B A Binary Search Tr ...

  7. PAT 甲级 1064 Complete Binary Search Tree (30 分)(不会做,重点复习,模拟中序遍历)

    1064 Complete Binary Search Tree (30 分)   A Binary Search Tree (BST) is recursively defined as a bin ...

  8. PAT Advanced 1064 Complete Binary Search Tree (30) [⼆叉查找树BST]

    题目 A Binary Search Tree (BST) is recursively defined as a binary tree which has the following proper ...

  9. 1064 Complete Binary Search Tree (30分)(已知中序输出层序遍历)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

随机推荐

  1. 使用cocos2d-x c++ Android静态库

    在用cocos2d-x做Android开发时,每次clean后都会需要再次编译coco2d-x的库,十分耗时. 这里给出一个直接使用静态库而不用每次都编译源码的方法: 1\ 首先找到一个cocos2d ...

  2. JavaScript实现快速排序

    思想: 通过分治思想.递归方法将数据依次分解为包含较小元素和较大元素的不同子序列 1.在数组中选择一个元素为基准 2.对数组进行遍历,小于基准的元素都移到基准的左边,大于基准的元素都移到基准的右边 3 ...

  3. 使用MLeaksFinder检测项目内存泄露总结

    前几天看到开源工具MLeaksFinder,决定用在公司的项目中试一下,效果很不错,用法也很简单,直接把项目文件夹拖到项目中就可以了,依靠这个项目,我发现公司项目中有不少内存泄露的地方,在此总结一下: ...

  4. vue新建项目

    一直都被如何用vue.js新建一个项目的问题困扰着,经过好久的实践,终于搞清楚如何用vue新建项目了: 1.官网对于vue-cli介绍: Vue.js provides an official CLI ...

  5. ARM、Intel、MIPS处理器啥区别?看完全懂了

    安卓支持三类处理器(CPU):ARM.Intel和MIPS.ARM无疑被使用得最为广泛.Intel因为普及于台式机和服务器而被人们所熟知,然而对移动行业影响力相对较小.MIPS在32位和64位嵌入式领 ...

  6. LeetCode 201 Bitwise AND of Numbers Range 位运算 难度:0

    https://leetcode.com/problems/bitwise-and-of-numbers-range/ [n,m]区间的合取总值就是n,m对齐后前面一段相同的数位的值 比如 5:101 ...

  7. POJ 2923 状压好题

    Relocation Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2631   Accepted: 1075 Descri ...

  8. 如何快速掌握一款新的MCU? (转)

      发布时间:2013-12-15 10:27:51 技术类别:单片机     个人分类:话题思考       任何一款MCU,其基本原理和功能都是大同小异,所不同的只是其外围功能模块的配置及数量.指 ...

  9. C# 进程和线程

    一.进程和线程 进程是对一段静态指令序列的动态执行过程,是系统进行资源分配和调度的基本单位.与进程相关的信息包括进程的用户标志.正在执行的已经编译好的程序.程序和数据在存储器中的位置等.同一个进程有可 ...

  10. S3C6410开发板开发环境的搭建

    本节主要介绍了S3C6410开发板及OK6410开发板.OK6410开发板是基于ARM11处理器的S3C6410,采用“核心版+底板”结构 主要步骤如下:. OK6410开发板自带一个串口,PC也需要 ...