04-树6 Complete Binary Search Tree (30 分)

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

我对稍复杂的递归函数真是一窍不通啊,代码除了GetLeftLength函数自己写的,其他都是在mooc视频上抄下来写的,唉,feel bad.

#include <math.h>
#include <stdio.h>
#include <stdlib.h>/*排序函数qsort需要的头文件*/
#define max 10000
int T[max], A[max];
int GetLeftLength(int n)
{
    int s;
    float c = 1; //记录数的层数
    while (1)
    {
        s = (int)(pow(2, c)) - 1; //几层的所有所有树节点
        c++;
        if ((pow(2, c) - 1) > n) /*如果下一层的满二叉树超过了输入的数的节点就退出,
                                且把层数减1,因为下一层的左子树最大节点数就是上一层的总结点数*/
        {
            c--;
            break;
        }
    }
    int Left = 0;
    if (n)
    {
        Left = (s - 1) / 2;    //左边 满二叉树层数减 1 的节点数
        int x = n - s;         //下一层多出,但没有满的节点数
        if (pow(2, c - 1) < x) //c-1 是因为每一层的总结点数是 2的 层数-1 次方
        {
            Left += (int)(pow(2, c - 1)); //下一层中左边最大的节点数是上一层的总结点数
        }
        else
        {
            Left += x;
        }
    }
    return Left;
}
void solve(int ALeft, int ARight, int TRoot) /*从A段中选出正确的数字,填到T[]根节点数组中*/
{                                            /*初始调用为solve(0,N-1,0)*/
    int n;
    int L;
    n = ARight + 1 - ALeft; /*计算树一共有多少个节点*/
    if (n == 0)
        return;           //递归先考虑需要一个结束条件
    L = GetLeftLength(n); /*计算出左子树的规模*/
    int LeftTRoot, RightTRoot;
    T[TRoot] = A[ALeft + L];   //根节点的下标是左子树的个数加1
    LeftTRoot = TRoot * 2 + 1; /*数组从0开始的树,根与儿子的关系是 Root*2+1
                                数组从1开始的树,关系是 Root*2 */
    RightTRoot = LeftTRoot + 1;
    solve(ALeft, ALeft + L - 1, LeftTRoot);
    /*ALeft + L - 1是指左子树的数组范围,刚才取到的根节点前一个值*/
    solve(ALeft + L + 1, ARight, RightTRoot);
    /*同理可得,ALeft + L + 1是指右子树的数组范围,刚才取到的根节点后一个值*/
}
int compare(const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
}
int main()
{
    int N;
    scanf("%d", &N);
    int i;
    for (i = 0; i < N; i++)
    {
        scanf("%d", &A[i]);
    }
    qsort(A, N, sizeof(int), compare);
    /*qsort函数每个变量注释:(要排序的数组,数值个数,数值类型,比较函数要自己写)*/
    solve(0, N - 1, 0); /*初始调用找第一个根节点为solve(0,N-1,0)*/
    for (i = 0; i < N; i++)
    {
        if (i)
        {
            printf(" %d", T[i]);
        }
        else
        {
            printf("%d", T[i]);
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

thoroughly strive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值