PAT甲 1064 Complete Binary Tree(30)

一、指针实现

这题拿到手想都不想直接采用了指针实现的二叉树进行递归求解。但实际上却忽略了完全二叉树可以采用静态数组来实现的特点,代码量大大加大。在第二部分附上简便做法。

#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<cmath>

using namespace std;

int N;
vector<int> input;

struct node{
	int data;
	node* lchild;
	node* rchild;
};

node* CBST(vector<int>& input,int start,int end){
	int root_index;
	if(start<=end){
		int num=end-start+1;
		int level=log((double)num+1)/log(2.0);
		//计算未填满的一层的结点个数
		int sub=num-((int)pow(2.0,level)-1);
		if(sub<=(int)pow(2.0,level-1)){//最后一层的结点均位于左子树
			root_index = start+(num-sub-1)/2+sub;
		}else{
			root_index = start+(num-sub-1)/2+(int)pow(2.0,level-1);
		}
		node* current=new node;
		current->data=input[root_index];
		current->lchild=CBST(input,start,root_index-1);
		current->rchild=CBST(input,root_index+1,end);
		return current;
	}else{
		return NULL;
	}
}

vector<int> levelOrder(node* root){
	vector<int> ans;
	queue<node*> to_visit;
	to_visit.push(root);
	while(to_visit.size()>0){
		node* current=to_visit.front();
		to_visit.pop();
		if(current!=NULL){
			ans.push_back(current->data);
			to_visit.push(current->lchild);
			to_visit.push(current->rchild);
		}
	}
	return ans;
}

int main(){
	scanf("%d",&N);
	for(int i=0;i<N;i++){
		int temp;
		scanf("%d",&temp);
		input.push_back(temp);
	}
	sort(input.begin(),input.end());

	node* root = CBST(input,0,N-1);

	vector<int> ans = levelOrder(root);
	for(int i=0;i<ans.size();i++){
		printf("%d",ans[i]);
		if(i!=ans.size()-1){
			printf(" ");
		}
	}

	return 0;
}

二、静态数组实现

完全二叉树可以采用静态数组实现。假设根节点下标为1.则i号结点的左儿子位于2i好结点,右儿子在2i+1号结点。根据二叉排序树的性质易得,二叉排序树的中序遍历必然是从小到大的一个序列。而静态数组本身又是二叉排序树的层序遍历。所以先建立一个静态数组,在对这个静态数组的二叉排序树采取中序遍历时,每次访问中间结点对其进行赋值即可。

参考代码:

#include <cstdio>
#include<vector>
#include <algorithm>
 
using namespace std;

int N,k=0;
vector<int> input;
void inOrder(vector<int>& CBST,int root){
	if(root > N)
	    return;
	else{
	    inOrder(CBST,2*root);
	    CBST[root] = input[k++];
	    inOrder(CBST,2*root+1);		
	}
}
 
int main(){
    scanf("%d",&N);
	for(int i=0;i<N;i++){
        int temp;
		scanf("%d",&temp);
        input.push_back(temp);
	}
	sort(input.begin(),input.begin()+N);
    vector<int> CBST(N+1);
    inOrder(CBST,1);
	for(int i=1;i<=N;i++){
	    printf("%d",CBST[i]);
        if(i!=N){
            printf(" ");
        }
    }
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值