04-树6 Complete Binary Search Tree

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

基本思路(MOOC浙大数据结构)

给定个数的结点,其完全二叉搜索树是唯一的,将序列排序后,又完美二叉树的性质,求得左子树的结点个数,分而治之的处理输入的序列,详细思路见陈越姥姥的讲解

PTA

代码如下

顺序结构
#include <stdio.h>
#include <math.h>
#define MaxSize 1000
typedef int ElementType;
//使用全局变量,储存输入的数据,便于函数调用
ElementType T[MaxSize];//结果树
ElementType Arr[MaxSize];//输入的数据

//对输入的数据,使用冒泡进行从小到大的排序
void sort(int n){
    int i,j;
    ElementType Temp;
    for ( i = 0; i < n; i++)
    for ( j = 0; j < n-i-1; j++){
        if(Arr[j]>Arr[j+1]){
            Temp=Arr[j+1];
            Arr[j+1]=Arr[j];
            Arr[j]=Temp;
            }
        }   
}
//计算完全二叉树的左子树的结点数
int GetLeftLength(int n){
    int H,X,L;
    H=(int)log2(n+1);
    X=n-pow(2,H)+1;
    int Y=pow(2,H-1);
    X=Y>X?X:Y;
    L=pow(2,H-1)+X-1;
    return L;
}
//递归进行完全二叉树的建立
void solve(int LeftLen,int RightLen,int Root){
    int n,L,LeftRoot,RightRoot;
    n=RightLen-LeftLen+1;
    if (n==0) return;
    L=GetLeftLength(n);
    T[Root]=Arr[LeftLen+L];
    LeftRoot=Root*2+1;
    RightRoot=LeftRoot+1;
    solve(LeftLen,LeftLen+L-1,LeftRoot);
    solve(LeftLen+L+1,RightLen,RightRoot);
}
int main()
{
    int N;
    scanf("%d",&N);
    for (int i = 0; i < N; i++)
        scanf("%d",&Arr[i]);
    sort(N);
    solve(0,N-1,0);
    for (int i = 0; i < N; i++)
    {
        if (i==N-1)
            printf("%d",T[i]);
        else
            printf("%d ",T[i]);

    }  
    return 0;
}

链式结构
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define MaxSize 1000
typedef int ElementType;
typedef struct TreeNode *BinTree;
struct TreeNode
{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};
//使用全局变量,储存输入的数据,便于函数调用
ElementType Arr[MaxSize];//输入的数据

//对输入的数据,使用冒泡进行从小到大的排序
void sort(int n){
    int i,j;
    ElementType Temp;
    for ( i = 0; i < n; i++)
    for ( j = 0; j < n-i-1; j++){
        if(Arr[j]>Arr[j+1]){
            Temp=Arr[j+1];
            Arr[j+1]=Arr[j];
            Arr[j]=Temp;
            }
        }   
}
//计算完全二叉树的左子树的结点数
int GetLeftLength(int n){
    int H,X,L;
    H=(int)log2(n+1);
    X=n-pow(2,H)+1;
    int Y=pow(2,H-1);
    X=Y>X?X:Y;
    L=pow(2,H-1)+X-1;
    return L;
}
//递归进行完全二叉树的建立
BinTree BuildTree(int LeftLen,int RightLen,BinTree Root){
    int n,L;
    n=RightLen-LeftLen+1;
    if (n==0) return NULL;
    L=GetLeftLength(n);
    Root=(BinTree)malloc(sizeof(struct TreeNode));
    Root->Data=Arr[LeftLen+L];
    Root->Left=BuildTree(LeftLen,LeftLen+L-1,Root->Left);
    Root->Right=BuildTree(LeftLen+L+1,RightLen,Root->Right);
    return Root;
}
void LevelorderTraversal (BinTree BT )//层序遍历
{ 
    BinTree Stack[MaxSize];
    BinTree T=BT;
    int Front=0,Rear=0;
    Rear=(Rear+1)%MaxSize;
    Stack[Rear]=BT;
    while (Rear!=Front)
    {
        Front=(Front+1)%MaxSize;
        T=Stack[Front];
        if (T->Left){
           Rear=(Rear+1)%MaxSize;
           Stack[Rear]=T->Left;
        }
        if (T->Right)
        {
            Rear=(Rear+1)%MaxSize;
            Stack[Rear]=T->Right;
        }
        if (Rear==Front)
            printf("%d",T->Data);
        else
            printf("%d ",T->Data);
    }
}
int main()
{
    int N;
    BinTree T=NULL;
    scanf("%d",&N);
    for (int i = 0; i < N; i++)
        scanf("%d",&Arr[i]);
    sort(N);
    T=BuildTree(0,N-1,T);
    LevelorderTraversal(T);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值