目次に戻る
タイトル
AVLツリー(バランスバイナリソートツリー)を構築します。
サンプル(コピー可能)
5
88 70 61 96 120
//output
70
7
88 70 61 96 120 90 65
//output
88
注意点
- この質問はもっと難しいです。PAT試験で行わない場合は、中央値を直接出力できます。7つのテストポイントのうち5つに合格すると、17ポイントを獲得できます。
- AVLツリー(バランスバイナリソートツリー)は、次の条件を満たす必要があります。①はバイナリソートツリーです。つまり、ツリーの各ノードの左側のサブツリーのすべてのノードはノードよりも小さく、各ノードの右側のサブツリーのすべてのノードはノード②各ノードの左右の高さの差の絶対値が1を超えることはできません
- バランスのとれたバイナリツリーを構築するプロセスでは、ローテーションが必要な状況が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;
}