OJ:https://www.patest.cn/contests/pat-a-practise/1064

(一)23分(3个case未过)代码

建树的规律是我瞎猜的。首先用样例数据分析。

         

对数据排序后:

0 1 2 3 4 5 6 7 8 9

有10个数据,因为是完全二叉树,底层应该有3个叶子,上层有1+2+4=7个结点。用以下代码计算:

    int up_num=,t=;
while(up_num + t* < n){
t*=;
up_num+=t;
}
int leaves_num=n-up_num;

0 1 2  |  3 4 5 6 7 8 9

将左侧叶子结点分割开,对右侧结点进行分析。

6就是根结点。计算方式是取中间。这个算法中所有的“取中间”都满足以下规律:

奇数个数:直接取中间

偶数个数:取中间靠右

定义以下函数计算:

int get_mid(int a,int b){
if((a+b)%){
return (a+b)/+;
}
return (a+b)/;
}

6就是从3到9取中间而来。之后就可以递归建树了。

6的左叶子是0到5取中间的3。

6的右叶子是7到9取中间的8。

……

23分代码:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map> #define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 1010
#define MAX (1<<30)-1
#define V vector<int> using namespace std; int a[LEN];
int n; typedef struct Node{
int d;
struct Node* l=NULL;
struct Node* r=NULL;
Node(int d=):d(d){
}
}; int get_mid(int a,int b){
if((a+b)%){
return (a+b)/+;
}
return (a+b)/;
} Node * build_tree(int s,int e) {
if(e<s) return NULL;
if(e==s) return new Node(a[s]);
int t=get_mid(s,e);
Node *node=new Node(a[t]);
node->l=build_tree(s,t-);
node->r=build_tree(t+,e);
return node;
} int main(){
// freopen("1064.txt","r",stdin);
I("%d",&n);
int i;
FF(i,n) I("%d",&a[i]);
sort(a,a+n);
int up_num=,t=;
while(up_num + t* < n){
t*=;
up_num+=t;
}
int leaves_num=n-up_num;
int root_i=get_mid(leaves_num,n-);
Node *root=new Node(a[root_i]);
root->l=build_tree(,root_i-);
root->r=build_tree(root_i+,n-);
queue<Node*> q;
q.push(root);
int cnt=;
while(!q.empty()){
Node* tmp=q.front();
q.pop();
cnt++;
O("%d",tmp->d);
if(cnt<n)
O(" ");
if(tmp->l)
q.push(tmp->l);
if(tmp->r)
q.push(tmp->r);
}
return ;
}

看了大佬的博客之后,才知道自己是多么naive。这题其实很简单,利用BST的性质:中序遍历的序列递增有序,再用dfs(其实深搜的本质就是中序遍历)和一个二叉堆来递归建树。最后都不用队列来模拟层序,直接把二叉堆依次输出就可以了。

AC代码:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map> #define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 10010
#define MAX 0x06FFFFFF
#define V vector<int> using namespace std; int n;
int a[LEN] ,ans[LEN];
int p=-; //p是中序遍历序列的索引,初始化为-1,因为在操作中首先会被+1而变成0 void dfs(int x){ //x是二叉堆(完全二叉树)的索引,根节点是0,叶子节点满足二倍关系
if(x>=n){ //超出界限
p++; //进行了一轮超出界限的操作,意味着操作序列的更新
return; //记得退出,不然会爆栈。找到目标解或者到了递归边界而退出是dfs的必须操作
}
dfs(x*+); //左子树递归
ans[x]=a[p]; //ans数组就是二叉堆,a是中序遍历序列。
dfs(x*+); //右子树递归
} int main(){
// freopen("D:\\input\\A1064.txt","r",stdin);
I("%d",&n);
int i;
FF(i,n) I("%d",&a[i]);
sort(a,a+n);
dfs();
FF(i,n){
O("%d",ans[i]);
if(i!=n-) O(" ");
}
return ;
}

BST | 1064 完全二叉搜索树的更多相关文章

  1. [leetcode]333. Largest BST Subtree最大二叉搜索树子树

    Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...

  2. 二叉搜索树(BST)详解

    前言:平衡树的前置知识吧 二叉搜索树的定义: 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于或等于它的根节点的值: (2)若右子树不空,则右子 ...

  3. BST(二叉搜索树)的基本操作

    BST(二叉搜索树) 首先,我们定义树的数据结构如下: public class TreeNode { int val; TreeNode left; TreeNode right; public T ...

  4. [Swift]LeetCode235. 二叉搜索树的最近公共祖先 | Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  5. 二叉搜索树-php实现 插入删除查找等操作

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的 ...

  6. [LeetCode] Serialize and Deserialize BST 二叉搜索树的序列化和去序列化

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  7. 数据结构中很常见的各种树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

    数据结构中常见的树(BST二叉搜索树.AVL平衡二叉树.RBT红黑树.B-树.B+树.B*树) 二叉排序树.平衡树.红黑树 红黑树----第四篇:一步一图一代码,一定要让你真正彻底明白红黑树 --- ...

  8. bst 二叉搜索树简单实现

    //数组实现二叉树: // 1.下标为零的元素为根节点,没有父节点 // 2.节点i的左儿子是2*i+1:右儿子2*i+2:父节点(i-1)/2: // 3.下标i为奇数则该节点有有兄弟,否则又左兄弟 ...

  9. 在二叉搜索树(BST)中查找第K个大的结点之非递归实现

    一个被广泛使用的面试题: 给定一个二叉搜索树,请找出其中的第K个大的结点. PS:我第一次在面试的时候被问到这个问题而且让我直接在白纸上写的时候,直接蒙圈了,因为没有刷题准备,所以就会有伤害.(面完的 ...

随机推荐

  1. windows下xshell连接虚拟机的CentOS 7

    1.虚拟机设置 2.虚拟机的“编辑”-“虚拟网络编辑器” 3.windows 中运行“cmd”,输入“ipconfig”查看ip,避免冲突 4.在虚拟机网络编辑器界面中,选择“VMnet8” 5.记住 ...

  2. luogu P2258 子矩阵 |动态规划

    题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第22.44行和第22.44.55列交叉 ...

  3. sql server生成随机id

    SQL Server中生成随机ID的函数是newId(),但是这样生成出来的随机ID是36位带[-]符号的. select newId(); -- 746516E0-95D6-4BAF-8826-6C ...

  4. MySQL常用系统表汇总

    在这篇文章中: MySQL5.7 默认模式 Information_schema performance_schema mysql sys MYSQL SHOW 命令 致谢 概述 本篇文章虽大部分内容 ...

  5. 一次kuberneets evicted的历险

    一.概述 kubernetes 的eviction检测diskpresure,检测的是kubelet的root-dir.kubelet的默认root-dir是/var/lib/kubelet,可以使用 ...

  6. 【BZOJ4016】[FJOI2014]最短路径树问题(点分治,最短路)

    [BZOJ4016][FJOI2014]最短路径树问题(点分治,最短路) 题面 BZOJ 洛谷 题解 首先把最短路径树给构建出来,然后直接点分治就行了. 这个东西似乎也可以长链剖分,然而没有必要. # ...

  7. 【03】Saltstack:远程执行

    写在前面的话 远程执行可以说是我们使用 Saltstack 最为基础的目的.所以在这里专门作为单独的一篇来详细的聊聊. 远程执行命令 示例命令: salt '*' cmd.run 'w' 命令分析: ...

  8. TCP的三次握手过程?为什么会采用三次握手,若采用二次握手可以吗

    谢希仁版<计算机网络>中的例子: "已失效的连接请求报文段”的产生在这样一种情况下: client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误 ...

  9. eclipse自定义导入或者编写版本格式化 xml

    1.自定义或者自己导入版本格式 window——preferences——java——Code style ——formatter(New 或者 import)

  10. 基于.NET平台常用的框架整理 转自 http://www.cnblogs.com/zhuyongblogs/p/5353751.html

    常用的一些开源组件整理: 导出Excel报表的插件:NOPI.dll(基于微软OpenXml实现)开源的作业调度和自动任务框架:Quartz.NET用于大数据搜索引擎的全文检索框架:Lucene.ne ...