PAT.A1066 AVLツリーのルート

目次に戻る

ここに画像の説明を挿入ここに画像の説明を挿入

タイトル

AVLツリー(バランスバイナリソートツリー)を構築します。

サンプル(コピー可能)

5
88 70 61 96 120
//output
70
7
88 70 61 96 120 90 65
//output
88

注意点

  1. この質問はもっと難しいです。PAT試験で行わない場合は、中央値を直接出力できます。7つのテストポイントのうち5つに合格すると、17ポイントを獲得できます。
  2. AVLツリー(バランスバイナリソートツリー)は、次の条件を満たす必要があります。①はバイナリソートツリーです。つまり、ツリーの各ノードの左側のサブツリーのすべてのノードはノードよりも小さく、各ノードの右側のサブツリーのすべてのノードはノード②各ノードの左右の高さの差の絶対値が1を超えることはできません
  3. バランスのとれたバイナリツリーを構築するプロセスでは、ローテーションが必要な状況が4つあります:LL、LR、RR、RL。どちらの場合も、左または右に回して、以下の参照コードを確認してください。手書きシミュレーションでは通常交換方式を使用しますが、実際のコードでは直接値を代入することができます。

直接中位数(17分)

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n,data[25];
	cin>>n;
	for(int i=0;i<n;i++)scanf("%d",&data[i]);
	sort(data,data+n);
	printf("%d",data[n/2]);
    return 0;
}

AVL

#include<bits/stdc++.h>
using namespace std;
struct node{
	int v,height;
	node *lc,*rc;
}*root; 
node* newnode(int v){
	node* no=new node;
	no->v=v;
	no->height=1;
	no->lc=no->rc=NULL; 
	return no;
}
int getheight(node* root){
	if(root==NULL)return 0;
	return root->height;
}
int getbalancenum(node* root){
	return getheight(root->lc)-getheight(root->rc);
}
void L(node* &root){
	node* tmp=root->rc;//tmp为新的root 
	root->rc=tmp->lc;//把tmp->rc裁剪下来
	tmp->lc=root;
	//只有root和tmp的高度发生了变化 
	root->height=max(getheight(root->lc),getheight(root->rc))+1;
	tmp->height=max(getheight(tmp->lc),getheight(tmp->rc))+1;
	root=tmp;
}
void R(node* &root){
	node* tmp=root->lc;
	root->lc=tmp->rc;
	tmp->rc=root;
	root->height=max(getheight(root->lc),getheight(root->rc))+1;
	tmp->height=max(getheight(tmp->lc),getheight(tmp->rc))+1;
	root=tmp;
}
void insert(node* &root,int v){
	if(root==NULL){
		root=newnode(v);
		return;
	}
	if(v<root->v){
		insert(root->lc,v);
		root->height=max(getheight(root->lc),getheight(root->rc))+1;
		if(getbalancenum(root)==2){
			if(getbalancenum(root->lc)==1){//LL型 
				R(root);//右旋 
			}else if(getbalancenum(root->lc)==-1){//LR型 
				L(root->lc);//先左旋 
				R(root);//再右旋 
			}
		}
	}else{
		insert(root->rc,v);
		root->height=max(getheight(root->lc),getheight(root->rc))+1;
		if(getbalancenum(root)==-2){
			if(getbalancenum(root->rc)==-1){//RR型 
				L(root);//左旋 
			}else if(getbalancenum(root->rc)==1){//RL型 
			    R(root->rc);//先右旋 
				L(root);//再左旋 
			}
		}
	} 
}
int main(){
	int n,v;
	cin>>n;
	while(n--){
		cin>>v;
		insert(root,v);
	}
	printf("%d\n",root->v);
    return 0;
}
公開された177元の記事 ウォンの賞賛5 ビュー6660

おすすめ

転載: blog.csdn.net/a1920993165/article/details/105518182