数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】

这篇具有很好参考价值的文章主要介绍了数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】

二叉搜索树 bst 被递归地定义为具有以下属性的二叉树

节点的左子树仅包含键小于节点键的节点
a 的右子树节点只包含键大于或等于节点键的节点
左右子树也必须是二叉搜索树
完全二叉树cbt是一棵完全充满可能异常的树从左到右填充的底层

现在给定一系列不同的非负整数键,如果要求树也必须是你认为的cbt,则可以构造一个唯一的bst输出此 bst 的层序遍历序列

输入规范
每个输入文件包含一个测试用例,每个案例第一行包含一个正整数 n ≤ 1000 然后 n 个不同的非负整数keys在下一行给出,一行中的所有数字用空格分隔,并且不大于2000

输出规范

 这道题需要的操作时排序并且需要遍历,最重要的一点它是个完全二叉树,所以数组是最适合的

这道题我的思路来自于浙江大学课件7.0.2完全二叉树

解题思路 

这道题说白就是将输入的样例构造成一个完全搜索二叉树。因为完全线索二叉树的根节点一定是是一个处于左右子树中间的那个值(搜索二叉树其根节点要比自己的左子树上所有节点都大又要比自己右子树上所有节点都小)然后我们的思路就是在排好序的样例上每次去找一下当前函数所在的树的根节点然后将其插入二叉搜索树对应的位置,然后直接输出即可,因为此时我们构建的树数组只要我们顺序遍历就是层序遍历。

int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int a;
        cin>>a;
        tree[i] = a;
    }
    //对输入样例排序
    sort(tree,tree+n,compare);
    solve(0,n-1,0);
    for(int i=0;i<n-1;i++)
        cout<<Ttree[i]<<" ";
    cout<<Ttree[n-1];

那么solve函数(排好序的样例上每次去找一下当前函数所在的树的根节点然后将其插入二叉搜索树对应的位置)该咋写呢?我们的思路是这样的,我们入函数的一定是所有样例,那么我们就是找整个样例的根节点,我们又知道根节点一定是是一个处于左右子树中间的那个值,然后我们的数组又是从0开始存值的,所以说其实在样例数组中左子树的个数加上此时这个树的左边界就可以确定此时这个树的根节点的值在样例数组的位置。

//得出左边节点个数
    int L = GetLeftLength(n);
    //左子树的个数就是此根节点的下标
    Ttree[rootIndex] = tree[L + Aleft];

然后我们找到最大的树的根节点,我们就可以继续递归去找它的左子树和右子树的根节点。这样这个函数该解决的问题就解决了。

//此节点的左节点在完全二叉树的下标
    int leftRootIndex = rootIndex * 2 + 1;
    //此节点的右节点在完全二叉树的下标
    int rightRootIndex = leftRootIndex + 1;
    solve(Aleft,Aleft+L-1,leftRootIndex);
    solve(Aleft+L+1,Aright,rightRootIndex);

但是如何找每个树的左子树的个数呢?

数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】

我们可以根据上图推出一个完全二叉树完美的那部分总共的个数(N)为pow(2,这个树的高度)-1+这个树减去完美部分的节点个数(X),

数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】 

 然后我们就可以通过上述的公式推出 树的高度(h)=log2(N+1-X) ,然后我们就可以通过这个算出X,(但是我们题目中需要算出的是左子树节点个数如下图是不满足L(左子树个数)=pow(2,h-1)-1+X1(左子树除了完美部分之外的个数)这个公式的,因为很可能右边也有节点)

数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】(像这样的情况就不满足)

所以X1=min(X,左子树最大值(pow(2,h-1)))

然后就可以根据公式L(左子树个数)=pow(2,h-1)-1+X1写出函数。

int GetLeftLength(int n){
    //将完全二叉树完美的部分的高度求出,由2的h次方 -1 +x = n推出
    int h = log2(n+1);
    //求出左边除去完满二叉树部分多余的节点
    int x = n - pow(2,h) + 1;
    int a = pow(2,h-1);
    x = min(x,a);
    //多余的节点 + 完美二叉树左边一边的节点
    int L = a - 1 + x;
    return L;
}

下面是完整代码 文章来源地址https://www.toymoban.com/news/detail-464270.html

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;
int compare(int a, int b){
    return a<b;
}
int tree[1001];
int Ttree[1001];
int GetLeftLength(int n){
    //将完全二叉树完美的部分的高度求出,由2的h次方 -1 +x = n推出
    int h = log2(n+1);
    //求出左边除去完满二叉树部分多余的节点
    int x = n - pow(2,h) + 1;
    int a = pow(2,h-1);
    x = min(x,a);
    //多余的节点 + 完美二叉树左边一边的节点
    int L = a - 1 + x;
    return L;
}
//后面的参数都是每次遍历时此时的树
//:Aleft:输入样例左边界,Aright:输入样例右边界,完全二叉树根节点下标
void solve(int Aleft,int Aright,int rootIndex){
    int n = Aright - Aleft + 1;
    // cout<<n<<endl;
    if(n==0) return;
    //得出左边节点个数
    int L = GetLeftLength(n);
    //左子树的个数就是此根节点的下标
    Ttree[rootIndex] = tree[L + Aleft];
    //此节点的左节点在完全二叉树的下标
    int leftRootIndex = rootIndex * 2 + 1;
    //此节点的右节点在完全二叉树的下标
    int rightRootIndex = leftRootIndex + 1;
    solve(Aleft,Aleft+L-1,leftRootIndex);
    solve(Aleft+L+1,Aright,rightRootIndex);
}
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int a;
        cin>>a;
        tree[i] = a;
    }
    //对输入样例排序
    sort(tree,tree+n,compare);
    solve(0,n-1,0);
    for(int i=0;i<n-1;i++)
        cout<<Ttree[i]<<" ";
    cout<<Ttree[n-1];
    return 0;
}

到了这里,关于数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java学数据结构(2)——树Tree & 二叉树binary tree & 二叉查找树 & AVL树 & 树的遍历

    1.树的出现:解决链表线性访问时间太慢,树的时间复杂度O(logN); 2.二叉树的定义,最多两个儿子节点; 3.二叉查找树,左小,右大,中居中;remove方法,两种,只有一个儿子节点,有两个儿子节点; 4.AVL树,在二叉查找树基础上加平衡条件,旋转方法,单旋转,双旋转;

    2024年02月10日
    浏览(38)
  • 二叉查找树(binary search tree)(难度7)

    C++数据结构与算法实现(目录) 答案在此:二叉查找树(binary search tree)(答案) 写在前面 部分内容参《算法导论》 基本接口实现 1 删除 删除值为value的第一个节点 删除叶子节点1 删除叶子节点1 (3)删除叶子节点1 删除有两个孩子的节点z 分成下面几个步骤进行: 1 找到

    2024年02月10日
    浏览(29)
  • 【C++】二叉搜索树Binary Search Tree

    二叉搜索树又被称为二叉排序树,顾名思义,当我们使用中序遍历时,会得到一个有序的序列。二叉搜索树有如下的性质: 1.若它的左子树不为空,则左子树上每个节点的值都小于根节点的值。 2.若它的右子树不为空,则右子树上每个节点的值都大于根节点的值。 3.左右子树

    2024年02月07日
    浏览(31)
  • 二叉搜索树(Binary Search Tree,BST)

    二叉搜索树(Binary Search Tree),也称二叉查找树或二叉排序树,是一种特殊的二叉树,它满足以下性质 对于二叉搜索树的每个节点 左子树中的所有节点的值都小于该节点的值 右子树中的所有节点的值都大于(或等于)该节点的值 对于二叉搜索树的任意节点,其左子树和右子

    2024年02月09日
    浏览(35)
  • 二叉搜索树(Binary_Search_Tree)

    二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值。 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。 它的左右子树也分别为二叉搜索树。 如: a、从根开始

    2024年04月28日
    浏览(25)
  • 最优二叉搜索树(Optimal Binary Search Tree)_20230401

    前言 如果有序数组或有序表中的各个元素查找概率相等,那么采用二叉搜索树(BST)进行折半查找,性能最优。如果有序表中各个记录的查找概率不相等,情况又如何呢? 先看一个具体例子。已知有序表keys, 同时给出各个元素的查询频率,注意到各个元素的查询频率不相同。

    2024年02月12日
    浏览(38)
  • 【C++庖丁解牛】二叉搜索树(Binary Search Tree,BST)

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,

    2024年03月28日
    浏览(43)
  • 【数据结构与算法】查找(Search)【详解】

    【知识框架】 查找(Searching) :就是根据给定的某个值,在查找表中确定一个其等于给定值的数据元素( 或记录)。 查找表(Search Table) :是由同一类型的数据元素(或记录)构成的集合。 (Key):数据元素中唯一标识该元素的某个数据项的值,使用基于的查找,查

    2024年02月02日
    浏览(37)
  • 数据结构:树(Tree)

    树是一种非线性结构,他是由n(n=0)个有限结点组成的一个具有层次关系的集合。 当n=0时,该树为空树。 在任意一个非空树中都满足以下条件: 1、有一个特殊的结点,称为根结点,根结点没有前驱结点 2、当n1时,其他结点可分为M(M0)个互不相交的有限集T1,T2,T3.……、

    2024年01月16日
    浏览(28)
  • 常见的数据结构:树Tree

    目录 1.概念 1.1 满二叉树 1.2 完全二叉树  1.3 平衡二叉树  2.遍历方式 2.1 先序遍历 2.2 中序遍历 2.3 后序遍历 2.4 层序遍历 原理:一种特殊的数据结构,每个节点有零个或多个子节点;没有父节点的节点称为根节点;每一个非根节点有且只有一个父节点;除了根节点外,每个子

    2024年02月13日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包