AVL树的插入删除操作

// Demo2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))


typedef struct AVLtree
{
    struct AVLtree * left,*right,*parent;
    int hight;
    int data;
}AVLTree,*PAVLTree;


PAVLTree rightleft(PAVLTree p);
PAVLTree leftright(PAVLTree p);
PAVLTree rightright(PAVLTree p);
PAVLTree leftleft(PAVLTree p);
PAVLTree insert(int x,PAVLTree p);
PAVLTree find(int data,PAVLTree p);
PAVLTree avl_delete(int data,PAVLTree p);
PAVLTree findMin(PAVLTree p);
PAVLTree findMax(PAVLTree p);
int Height(PAVLTree p);

PAVLTree findMin(PAVLTree p)
{
    while(p && p->left)
    {
        p = p->left;
    }
    return p;
}
PAVLTree findMax(PAVLTree p)
{

    while(p && p->right)
    {
        p = p->right;
    }
    return p;
}

//删除节点可能会导致根节点的改变,所以必须返回根节点,以利于后面的操作
PAVLTree avl_delete(int data,PAVLTree p)
{
    if(!p) return NULL;
    while(1)
    {
        if(data > p->data)
        {
            p=p->right;
            if( (Height(p->right)-Height(p->left)) ==2 )
            {
                if(data<p->right->data)
                {
                    p=rightleft(p);
                }else
                {
                    p=rightright(p);
                }
            }
        }else if( data < p->data )
        {	
            p=p->left;
            if( (Height(p->left)-Height(p->right)) ==2 )
            {
                if(data >  (p->left->data) )
                {
                    p=leftright(p);
                }else
                {
                    p=leftleft(p);
                }
            }
        }else if(p->left && p->right)
        {
            PAVLTree t = findMin(p->right);
            p->data = t->data;
            
            data=t->data;
            p=p->right;
        }else
        {
            PAVLTree t = p->parent;
            
            if(t->left && t->left->data == data)
            {
                t->left=NULL;
            }else if(t->right &&  t->right->data==data)
            {
                t->right = p->right;
            }
            p->left=p->right=NULL;
            free(p);
            p=NULL;
            p=t;
            break;
        }
        if(p)
            p->hight = max(Height(p->left),Height(p->right))+1;
    }
    
    while(p)
    {
        p->hight = max(Height(p->left),Height(p->right))+1;

        if( (Height(p->left)-Height(p->right)) ==2 )
        {
            if(p->left->left->hight < p->left->right->hight)
            {
                p =leftright(p);
            }else
            {
                p=leftleft(p);
            }
        }

        if( (Height(p->right)-Height(p->left)) ==2 )
        {
            if(p->right->left->hight>p->right->right->hight)
            {
                p=rightleft(p);
            }else
            {
                p=rightright(p);
            }
        }
        if(p->parent)
            p=p->parent;
        else break;
    }
    return p;
}


PAVLTree find(int data,PAVLTree p)
{
    while(p)
    {
        if(data >p->data)
            p = p->right;
        else if(data < p->data)
            p = p->left;
        else
            return p;
    }

    return NULL;
}

int Height(PAVLTree p)
{
    if(p==NULL)
        return -1;
    else
        return p->hight;
}
PAVLTree leftright(PAVLTree p)
{
    PAVLTree tmp=rightright(p->left);
    p->left=tmp;
    tmp->parent=p;
    return leftleft(p);

}
PAVLTree leftleft(PAVLTree p)
{ 
    PAVLTree t = p->left;

    p->left =t->right;
    if(p->left)
        p->left->parent=p;
    p->parent=t;
    t->right=p;
    t->parent=NULL;

    p->hight = max(Height(p->left),Height(p->right))+1;
    t->hight = max(Height(t->left),Height(t->right))+1;

    return t;
}//=====================================================================================================

PAVLTree rightleft(PAVLTree p)
{
    PAVLTree tmp= leftleft(p->right);
    p->right = tmp;
    tmp->parent=p;
    return rightright(p);
}

PAVLTree rightright(PAVLTree p)
{
    PAVLTree t= p->right;
    p->right=t->left;
    if(p->right)
        p->right->parent=p;
    p->parent=t;

    t->left=p;
    t->parent=NULL;

    p->hight = max(Height(p->left),Height(p->right))+1;
    t->hight = max(Height(t->left),Height(t->right))+1;

    return t;
}

PAVLTree insert(int x,PAVLTree p)
{
    if(p==NULL)
    {
        p = (PAVLTree)malloc(sizeof(AVLTree));
        if(p==NULL)
        {
            return NULL;
        }else
        {
            p->data=x;
            p->left=p->right=p->parent=NULL;
            p->hight=0;
        }
    }else if(x < p->data )
    {
        p->left=insert(x,p->left); // 80   
        p->left->parent = p;
        if( (Height(p->left)-Height(p->right)) ==2 )
        {
            if(x >  (p->left->data) )
            {
                p=leftright(p);
            }else
            {
                p=leftleft(p);
            }
        }
    }else if(x > p->data)
    {
        //返回的值是为了计算深度
        p->right = insert(x,p->right);
        p->right->parent =p;
        if( (Height(p->right)-Height(p->left)) ==2 )
        {
            if(x<p->right->data)
            {
                p=rightleft(p);
            }else
            {
                p=rightright(p);
            }
        }
    }
    p->hight = max(Height(p->left),Height(p->right))+1;

    return p;
}

void print_tree(PAVLTree t)
{
    if(t)
    {
        cout<<t->data<<" ";
        print_tree(t->left);
        print_tree(t->right);
    }
}



int _tmain(int argc, _TCHAR* argv[])
{
    AVLTree *pt=NULL;
/*
    pt=insert(100,pt);
    pt=insert(80,pt);
    pt=insert(110,pt);
    pt=insert(70,pt);
    pt=insert(85,pt);
    pt=insert(60,pt);
    */

    //测试左右旋转
/*
    pt=insert(120,pt);
    pt=insert(110,pt);
    pt=insert(150,pt);
    pt=insert(70,pt);
    pt=insert(111,pt);
    pt=insert(115,pt);
    */

    pt=insert(150,pt);
    pt=insert(130,pt);
    pt=insert(180,pt);
    pt=insert(170,pt);
    pt=insert(200,pt);
    pt=insert(160,pt);
    pt=insert(161,pt);
    pt=insert(162,pt);
    pt=insert(165,pt);

    print_tree(pt);
    cout<<endl;
    cout<<find(180,pt)->data<<endl;
    cout<<"Max = "<<findMax(pt)->data<<endl;
    cout<<"Min = "<<findMin(pt)->data<<endl;
    pt=avl_delete(161,pt);
    cout<<" After del 161"<<endl;
    print_tree(pt);
    pt=avl_delete(200,pt);
    pt=avl_delete(162,pt);
    cout<<endl;
    cout<<" After del 200"<<endl;
    print_tree(pt);

    getchar();
    return 0;
}

细节后续完善…

    原文作者:AVL树
    原文地址: https://blog.csdn.net/c_upsoft/article/details/50737631
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞