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:

  1. 10
  2. 1 2 3 4 5 6 7 8 9 0

Sample Output:

  1. 6 3 8 1 5 7 9 0 2 4
  2.  
  3. 这道题考察的点是二叉搜索树和完全二叉树。刚开始我第一反应就是完全二叉树的性质:用数组存储的话,父节点下标为i,左孩子为2i,右孩子为2i+1。而一个完全二叉搜索树的最小节点肯定在最左边。我一开始的想法是用数组存储,找到最左边那个位置,放进去0,然后找到0的父节点,放1,再放右节点的2,再往上一直放,但是当时没想到用递归,觉得这样写会很麻烦,所以放弃了。
    接着我用了最普通的链式方法建树,然后层序遍历输出。不得不说,链式方法建树很繁琐,我调试了很久才通过。具体思路是,先把输入数据放在一个vector里面,然后排序,从小到大排。然后找出整个树的根节点的下标(找的方法是先计算左子树有几个节点),再递归,在左子树再建树。这样非常麻烦,写递归的时候很容易出错。
    后来AC之后在网上搜了搜,发现有非常好的做法。其实我一开始的想法类似,但是没有更进一步去想。一个完全二叉搜索树的中序遍历的结果就是递增排列的,那么我们采用中序遍历的方法去建树(即遍历的时候,visit操作是给节点赋值!)。这种逆向思维是我之前完全没想到的,这次学习了。总之就是,采用中序遍历的方法,利用完全二叉树的父子节点关系去建树,最后把数组按序输出即可。
    下面我把两种方法的代码都贴上来。很明显,第一段代码明显比第二段简单得多得多得多得多!!!
  1. #include<iostream>
  2. #include<vector>
  3. #include<algorithm>
  4. using namespace std;
  5.  
  6. int N;
  7. int pos=;
  8. int *tree;
  9. vector<int> vec;
  10.  
  11. void build(int n)
  12. {
  13. if (n>N) return;
  14. else
  15. {
  16. build(n*);
  17. tree[n] = vec[pos++];
  18. build(n*+);
  19. }
  20. }
  21.  
  22. int main()
  23. {
  24. int element;
  25. cin >> N;
  26. tree = new int [N+];
  27. //输入元素并排序
  28. for (int i=;i<N;i++)
  29. {
  30. cin >> element;
  31. vec.push_back(element);
  32. }
  33. sort(vec.begin(),vec.end());
  34.  
  35. build();
  36. cout << tree[];
  37. for (int i=;i<=N;i++)
  38. cout << ' ' << tree[i];
  39. return ;
  40. }
  1. #include<iostream>
  2. #include<vector>
  3. #include<cmath>
  4. #include<queue>
  5. #include<algorithm>
  6. using namespace std;
  7.  
  8. typedef struct node* tree;
  9. struct node
  10. {
  11. int data;
  12. tree left;
  13. tree right;
  14. };
  15.  
  16. tree BuildTree (tree,int,unsigned,unsigned);
  17. int FindRoot(int,int);
  18. void LevelOrderTraversal(tree T);
  19. vector<int> vec;
  20.  
  21. int main()
  22. {
  23. int N,element;
  24. cin >> N;
  25.  
  26. //输入元素并排序
  27. for (int i=;i<N;i++)
  28. {
  29. cin >> element;
  30. vec.push_back(element);
  31. }
  32. sort(vec.begin(),vec.end());
  33.  
  34. unsigned b=,e=vec.size()-;
  35.  
  36. int root=FindRoot(N,);
  37. tree T = nullptr;
  38. T=BuildTree(T,root,b,e);
  39.  
  40. LevelOrderTraversal(T);
  41.  
  42. return ;
  43. }
  44.  
  45. int FindRoot(int N,int base)
  46. {
  47. int level=int(log(double(N))/log(2.0))+; //共有这么多层
  48. int root=;
  49. if (N == )
  50. root = ;
  51. else if (N == )
  52. root = ;
  53. else if (N==)
  54. root = ;
  55. else
  56. if (N-(pow(double(),double(level-))-) > pow(double(),double(level-)) )//左子树满了
  57. root = pow(double(),double(level-))-;
  58. else
  59. root = pow(double(),double(level-))-+N-(pow(double(),double(level-))-);
  60. return root+base;
  61. }
  62.  
  63. tree BuildTree(tree T,int root,unsigned b,unsigned e)
  64. {
  65. //cout << b << e << endl;
  66. if (e==b)
  67. {
  68. T=new node;
  69. T->data = vec[b];
  70. T->left = nullptr;
  71. T->right = nullptr;
  72. }
  73. else
  74. {
  75. T = new node;
  76. T->data = vec[root];
  77. T->left = BuildTree(T,FindRoot(root-b,b),b,root-);
  78. if (e!=root)
  79. T->right= BuildTree(T,FindRoot(e-root,root+),root+,e);
  80. else
  81. T->right = nullptr;
  82. }
  83. return T;
  84. }
  85.  
  86. void LevelOrderTraversal(tree T)
  87. {
  88. bool flag=true;
  89. queue<tree> Q;
  90. if (!T) return;
  91. Q.push(T);
  92. while (!Q.empty())
  93. {
  94. if (flag)
  95. {
  96. cout << Q.front()->data;
  97. flag = false;
  98. }
  99. else
  100. cout << ' ' << Q.front()->data;
  101. if (Q.front()->left)
  102. Q.push(Q.front()->left);
  103. if (Q.front()->right)
  104. Q.push(Q.front()->right);
  105. Q.pop();
  106. }
  107. }
  1.  

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. linux查找进程,查找僵死进程,查找僵死进程并自动杀掉

    查找进程: ps -aux | grep  flume  /  netstat -anop | grep 8080(端口号) 常规杀进程: kill  pid 查看僵死进程: ps -A -o sta ...

  2. volatile关键字及编译器指令乱序总结

    本文简单介绍volatile关键字的使用,进而引出编译期间内存乱序的问题,并介绍了有效防止编译器内存乱序所带来的问题的解决方法,文中简单提了下CPU指令乱序的现象,但并没有深入讨论. 以下是我搭建的博 ...

  3. CSS3支持box-flex弹性布局

    <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...

  4. 利用mysql_multi来管理多实例:

    mysql_multi的现实意义: 1:随着连接数上升,性能会下降,通过多实例来分流大量连接来提高性能. 2:做资源隔离 3:分库分表 mysql_multi是官方管理多实例的一个脚本,利用perl语 ...

  5. SQL server 查询某个表在哪些存储过程(SP)中使用到

    1.查询某个表被哪些存储过程(以下简称 SP)使用到 : select distinct object_name(id) from syscomments where id in (select ob ...

  6. YCSB-压测

    安装 wget http://download.oracle.com/otn-pub/java/jdk/7u40-b43/jdk-7u40-linux-x64.rpm #注意此处到官网下载后上传,需要 ...

  7. lock

    #ifndef lock_h #define lock_h #include <stdint.h> #include <string.h> #include "myd ...

  8. html中frameset简介

    1, 只 要 <FRAMESET> <FRAME> 两个标签,框架便是网页画面分成几个框窗,同时取得多个 URL. 2, 该框架只记录如何划分,不会显示任何资料.所以不必放入 ...

  9. Delphi 中同类型方法的说明

    对象的方法能定义成静态(static).虚拟(virtual).动态(dynamic)或消息处理(message).请看下面 的例子: TFoo = class procedure IAmAStati ...

  10. 也说析构---C++

    正如我们知道的: 通过new分配到heap中的对象,当对其delete,才会被析构: 分配在stack中的对象,当其离开作用域时被析构: