Complete Binary Search Tree (30分)【C语言】计算根结点位置 / 二叉搜索树中序遍历和完全二叉树性质

题目:

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.

输入格式

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.

输出格式

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.

输入样例

10
1 2 3 4 5 6 7 8 9 0

输出样例

6 3 8 1 5 7 9 0 2 4

算法

每次计算根节点位置

假设所求完全二叉搜索树已经存在。层序遍历每个结点位置。求出当前节点在序列中的位置,直接输出。

代码实现

#include<math.h>
#define MIN(a,b) (a<b?a:b)
int *DynamicArray(int n)
{
	int *A=(int*)malloc(sizeof(int)*n);
	int i=0;
	for(i=0;i<n;i++)A[i]=-1;
	return A;
}
int main()
{	
	int n=0;
	scanf("%d",&n);
	int* A=DynamicArray(n);
	int i=0;
	for(i=0;i<n;i++){
		scanf("%d",&A[i]);
	}
	Select_Sort(A,n);
	CompleteBinaryTree(A,n);
	return 0;
}
		

CompleteBinaryTree:利用Sequence队列对数组A进行层序遍历。
计算出当前序列的根节点位置,打印输出后,将子数组压入堆栈。

typedef struct ElementType{
	int *Array;
	int Num;
}Element;
void CompleteBinaryTree(int A[],int N)
{
	int *B=DynamicArray(N);
	Element Sequence[N];
	Element Temp={.Array=NULL,.Num=-1};
	int head=-1,rear=-1;
	Temp=(Element){A,N};
	Sequence[++rear]=Temp;
	int i=0,k=-1;
	for(i=0;i<N;i++){
	    Temp=Sequence[++head];
	    k=Calculate(Temp);//k代表位置
	    B[i]=Temp.Array[k]; 
	    if(i!=0){
	        printf(" ");
	    }
	    printf("%d",B[i]);
	    if(k>0){
	        Sequence[++rear]=(Element){Temp.Array,k};
	    }
	    if(0<k&&k<Temp.Num){
	        Sequence[++rear]=(Element){Temp.Array+k+1,Temp.Num-k-1};
	    }
	}
	for(i=0;i<N;i++){
	    A[i]=B[i];
	}
}	

Calculate:计算当前序列的根节点位置

 int Calculate(Element Temp)
{ 
	int subscript=-1;
	int *A=Temp.Array;
	int N=Temp.Num;
	if(N==1){
	    subscript=0;
	}else{
	    int k=0; 
	    int sum=0;
	    while(sum<N){
	        k++;
	        sum=pow(2,k)-1;
	    }
	    if(sum>N)k--;//完美二叉树层数
	    int remainder=N-pow(2,k)+1;//最后一层剩余结点个数
	    if(remainder==0){
	        subscript=(N-1)/2;
	    }else{
	        int k1_half=pow(2,k-1);
	        subscript=(N-remainder-1)/2+MIN(remainder,k1_half) ;
	    }
	}
	return subscript;
}		

Select_Sort:选择排序

void Swop(int *a,int *b)
{
	int c=*a;
	*a=*b;
	*b=c;
}
void Select_Sort(int A[],int N)
{
	int min=0,sub=-1;
	int i=0,j=0;
	for(i=0;i<N-1;i++){
	    min=A[i];
	    for(j=i+1;j<N;j++){
	        if(min>A[j]){
	            min=A[j];
	            sub=j;
	        }
	    }
	    if(min<A[i]){
	        Swop(&A[i],&A[sub]);
	    }
	}
}

二叉搜索树中序遍历和完全二叉树性质

输入数组从小到大排序后所对应的序列 和最终CBT(完全二叉搜索树树)中序遍历得到的序列 是一致的。

代码实现

#define MAXSIZE 1001
int A[MAXSIZE];
int CBT[MAXSIZE];
int count=0;
int N;
int main()
{
	scanf("%d",&N);
	int i=0;
	for(i=1;i<=N;i++){
	    scanf("%d",&A[i]);
	}
	SelectSort();
	InOrder(1);
	CompleteBinaryTree();
	for(i=1;i<=N;i++){
	    if(i!=1){
	        printf(" ");
	    }
	    printf("%d",CBT[i]);
	}
	return 0;
}

SelectSort:对输入数组A进行选择排序

void SelectSort()
{
	int n=N;
	int i=0,j=0;
	int min=0,sub=-1;
	for(i=1;i<n;i++){
	    min=A[i];
	    for(j=i+1;j<=n;j++){
	        if(min>A[j]){
	            min=A[j];
	            sub=j;
	        }
	    }
	    if(min<A[i]){
	        A[sub]=A[i];
	        A[i]=min;
	    }
	}
}	 	 

InOrder:中序遍历CBT(完全二叉搜索树),把排好序的A数组中的元素放置CBT对应位置

void InOrder(int root)
{
	if(root>N)return;
	InOrder(root*2);
	CBT[root]=A[++count];
	InOrder(root*2+1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值