AVL树(平衡二叉树)

来源:互联网 发布:java ffmpeg 视频转码 编辑:程序博客网 时间:2024/06/17 08:14

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

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

#include <iostream>#include<windows.h>#define MAX 100using 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;}


原创粉丝点击