AVL树(平衡二叉树)

AVL树的旋转操作详解及C++实现

AVL树通过旋转操作来维持其“平衡”,即尽可能接近满二叉树的形状,这样才能在查找等操作时发挥树结构的优势,达到log(n)的速度,否则一个退化的二叉树就成链表了。

AVL树的旋转操作不难理解,找个带插图的文章看看就很容易明白,不过实现起来就比较麻烦,主要在于情况分类比较多,一会这个节点要认爹一会那个节点要换儿子,最好能自己在纸上把所有情况画一画。

#include <iostream>
#include<windows.h>
#define MAX 100
using namespace std;
struct node{
	int n;
	int b;
	node *l,*r;
	node(int nn){
		n=nn; b=0;
		l=r=NULL;
	}
};
struct btree{
	node *root;
	node *sta[MAX];
	int top;
	btree(){
		root=NULL;
	}
	void single(node *F,node *A,node *B,int flag){ // flag=1,右旋; 0左旋
	    node **bch; bch=flag? &(B->r) : &(B->l);
        node **ach; ach=flag? &(A->l) : &(A->r);
        *ach=*bch;
        *bch=A;
        if(F!=NULL){
            if(F->l==A) F->l=B;
            else F->r=B;
        }
        else root=B;
	}
	void revolve(node *B,node *A){
	    node *F=sta[top];
	    int flag= A->b > 0 ? 1:0;
	    node *C=flag?B->r:B->l;
	    if(A->b*B->b>0){
            single(F,A,B,flag);
            A->b=0; B->b=0;
	    }
	    else{
	        single(A,B,C,1-flag);
	        single(F,A,C,flag);
	        if(A->b*C->b>0){
                B->b=0; A->b=-C->b;
	        }
	        else{
	            A->b=0; B->b=-C->b;
	        }
	        C->b=0;
	    }
	}
	void checkbalance(node *p){
        node *q;
        while(q=sta[top--]){
            if(p==q->l) q->b++;
            else q->b--;
            if(q->b==0) break;
            if(q->b==2||q->b==-2){
                revolve(p,q);
                break;
            }
            p=q;
        }
	}
	void insert(int n){
        node **p=&root;
        top=0; sta[top]=NULL;
        while((*p)){
            sta[++top]=*p;
            if( n < (*p)->n ) p=&((*p)->l);
            else p=&((*p)->r);
        }
        *p=new node(n);
        checkbalance(*p);
	}
	bool creat(){
	    int n;
	    cout<<"请输入若干数据,以Ctrl+Z结束\n";
	    cout<<"(直接输入Ctrl+Z退出程序)\n";
		while(cin>>n) insert(n);
		cin.clear();
		if(root==NULL) return 1;
		else return 0;
	}
	bool srch(int n){
        node *p=root;
        while(p){
            if(p->n==n) return 1;
            else if(p->n<n) p=p->r;
            else p=p->l;
        }
        return 0;
	}
};
int main(){
	while(1){
		btree t;
		if(t.creat()) break;
		while(1){
            cout<<"请选择功能, 1.查找; 2.插入新元素; 3.重建一个树: ";
            int sel,n;
            cin>>sel;
            if(sel==1){
                cout<<"请输入要查找的值: ";
                cin>>n;
                if(t.srch(n)) cout<<"  查找成功!\n";
                else cout<<"  查找失败!\n";
            }
            else if(sel==2){
                cout<<"请输入要插入的值: ";
                cin>>n;
                t.insert(n);
                cout<<"  插入成功!\n";
            }
            else{
                system("cls");
                break;
            }
		}
	}
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值