数据结构第七周笔记(2)——图(中)(慕课浙大版本--XiaoYu)

103 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第19天,点击查看活动详情

树习题-CBST.2 核心算法

如果我们知道左子树一共包含了多少个结点,那就知道根结点R上放的一定是从小到大排第几位的那个数字

如何知道左子树有多少个结点呢?

  1. 给定n个数之后,完全二叉树的结构是固定的,可以非常准确的算出左边一共多少个结点
  2. 先给我们要输入的序列从小到大排一个序列。根据完全二叉树一共有多少个结点,通过导出的公式是可以精确计算他的左子树一共有多少个结点
  3. image-20220730200103573典型先序遍历的应用

核心算法

image-20220730215836941

TRoot是树T根结点所在的位置,那个元素的下标存在TRoot里面

void solve(int ALeft,int ARight,int TRoot)
{
    //初始调用为solve(0,N-1,0)->A的起始点就是A的第0个元素,A的终止点就是A的最后一个元素(N-1是他的下标),结果树T是完全二叉树,他的根结点一定存在T[0]这个位置,所以刚开始传入的是0
    //整个函数要完成的任务就是从A传进去的这一段里面选出一个正确的数字,填到我们结果的这颗树,TRoot的这颗树上
    n = ARight - ALeft + 1;//这一段里面元素总个数n(最右边下标减去最左边下标加上1)
    if(n == 0) return;
    L = GetLeftLenght(n);//计算出n个结点的树(完全二叉树)其左子树有多少个结点 
    T[TRoot] = A[ALeft + L];
    //左孩子的下标是多少?正常情况下根结点是TRoot的话那他的左孩子下标应该是TRoot×2,但是那是在堆里面(堆的第0个元素是存放哨兵的地方,不是用来存真实值的),在本题中是从0开始算下标的
    LeftRoot = TRoot * 2 + 1;//(例子:左孩子第一个元素0*2+1为1,第二个3...)
    RightTRoot = LeftTRoot + 1;//(例子:右孩子第一个元素1+1为2,第二个4...)
    //准备递归左右边
    solve(ALeft,ALeft + L - 1,LeftTRoot);//左边,ALeft + L - 1是取掉根结点元素的前一个值
    solve(ALeft + L + 1,ARight,RightTRoot);//右边
    
}

排序(目前凑合用的,后面详细讲解使用)

库函数:qsort

#include<stdlib.h>//调用qsort
int main()
{
    ....
    qsort(A,N,sizeof(int),compare);//根据返回的两个数是正数还是负数还是0来决定两个元素谁排在前面或者后面或者不做交换
    //第一个参数:待排序序列的首元素的位置(就是把读进来的数存在一个叫A的数组里面)也就是说如果我们要将数组排序的话,这个就是数组首元素的地址
    //第二个参数:代排序列的总长度(一共要排N个元素)
    //第三个参数:要排元素的大小
    //第四个参数:不是变量,是一个函数的名字(可以不叫compare,这个随意),他的作用是比较两个元素的大小。因为qsort就是比较一对元素的大小来决定哪个元素应该在前面的,哪个元素应该在后面的
    ....
}
​
    /*compare标准接口
    int compare(const void*a,const void*b)传入的是两个带比较元素的指针。需要返回的是三种整数之一(负数正数或者0,这里浙大的课程中字幕第一次出错负数显示为复数,但其实是负数,需要注意)
    {
        return *(int*)a - *(int*)b;//后序也可以非常复杂
    }
    */

树习题-CBST.3 计算左子树的规模

h是层数

image-20220730232211145

真正计算H的时候X的出来的可能不是整数,但不要紧,X是多少都没有关系,求H的话可以忽略掉X然后的出来的答案向下取整即可。得到的H就是完美二叉树层数(H),然后就可以反算出X了

完美二叉树的左子树:image-20220730232601997

image-20220730232638342

如果X的个数蔓延到右子树那边去的话(就是最后一层的x跑到右边去,那上面左子树的式子就不能加上X)

所以我们需要知道最下面一层x的最大值和最小值可以取多少

  1. 在这个式子中,最小值X要取到0(为什么不是1而是0呢?L是左子树哦)image-20220730233019880

    1. 因为在上述式子中H至少为2啦,H为1是根结点的位置层数,左子树至少从第二层开始,最少只有他自己一个
  2. 要使 img 得到正确结果,img能取的最大值是

    1. image-20220730233616555
  3. 完整步骤:

    1. image-20220730233846536