码迷,mamicode.com
首页 > 其他好文 > 详细

AVL树插入删除

时间:2016-10-17 21:02:52      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:

写了好久,感觉插入和删除麻烦些,插入也就4种情况,但只要写两个函数,左左和右右的,左右的情况是以根节点的左子树为头进行一次右右旋转,使它变成左左的情况,再左左旋转下就下,右左的也一样;

另外就是删除,先是判断要删除的节点右儿子是否为空,是空,直接删,否则找到它最左边的儿子来替代它,然后就是高度的更新,重新的旋转。。。

哎,真实花了我好长时间,不过终于写完了。大致感觉没啥问题了吧,有的话以后再改吧。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <cmath>

using namespace std;


typedef struct AvlNode              // AVL树的节点
{
    int data;
    struct AvlNode *left;           // 左孩子
    struct AvlNode *right;          // 右孩子
    int Height;
}*Position,*AvlTree;

AvlTree MakeEmpty(AvlTree T);
Position Find(int x,AvlTree T);
Position Find_right(AvlTree T);
Position FindMax(AvlTree T);

int Search(AvlTree T);
AvlTree  Insert(int x,AvlTree T);
AvlTree  Delete(int  x,AvlTree T);

AvlTree left_left(AvlTree k1);
AvlTree right_right(AvlTree k1);
AvlTree left_right(AvlTree k1);
AvlTree right_left(AvlTree k1);
AvlTree Printf_tree(AvlTree T);
AvlTree balance(AvlTree T);

int main()
{
    AvlTree T =NULL;
    getchar();
   T=Insert(2,T);
   T= Insert(7,T);
     //Printf_tree(T);
    T= Insert(5,T);
    //Printf_tree(T);
    T=Insert(11,T);
    T=Insert(9,T);
    T=Insert(10,T);
    T=Insert(100,T);
    T=Insert(14,T);
    T=Insert(20,T);
   Printf_tree(T);
  T = Delete(5,T);
   printf("\n");
   Printf_tree(T);
    printf("\n");
    T = Delete(2,T);
     Printf_tree(T);
    getchar();
    return 0;
}
AvlTree MakeEmpty(AvlTree T)
{
    if(T!=NULL)
    {
        MakeEmpty(T->left);
        MakeEmpty(T->right);
        free(T);
    }
    return NULL;
}

int height(AvlTree T)
{
    if(T==NULL)return -1;
    else return T->Height;
}

//向树中插入数据
AvlTree Insert(int x,AvlTree T)
{
    if(T==NULL)
    {
        T = (AvlTree)malloc(sizeof(struct AvlNode));
        T->data = x;
        T->Height = 0;
        T->left = NULL;
        T->right = NULL;
    }
    //如果插入元素小于当前元素
    else if(x<T->data)
    {
        T->left = Insert(x,T->left);
        if(height(T->left)-height(T->right)==2)
        {
            if(x<T->left->data)
                T = left_left(T);
            else
                T = left_right(T);
        }

    }
    else if(x>T->data)
    {
        T->right = Insert(x,T->right);
        if(height(T->right)-height(T->left)==2)
        {
            if(x<T->right->data)
                T = right_left(T);
            else
                T = right_right(T);
        }
    }
    T->Height = max(height(T->left),height(T->right))+1;
    return T;
}

//左左旋转
AvlTree left_left(AvlTree k1)
{
    //if(height(k1->left)-height(k1->right)<2)return k1;
    AvlTree k2 = k1->left;
    k1->left = k2->right;
    k2->right = k1;
   k1->Height = max(height(k1->left),height(k1->right))+1;
    k2->Height = max(height(k2->left),height(k2->right))+1;
    return k2;
}

//右右旋转

AvlTree right_right(AvlTree k1)
{
    //if(height(k1->right)-height(k1->left)<2)return k1;
    AvlTree k2 = k1->right;
    k1->right = k2->left;
    k2->left = k1;
    k1->Height = max(height(k1->left),height(k1->right))+1;
    k2->Height = max(height(k2->left),height(k2->right))+1;
    return k2;
}

//左右旋转

AvlTree left_right(AvlTree k1)
{
    k1->left = right_right(k1->left);
    return left_left(k1);
}

//右左旋转

AvlTree right_left(AvlTree k1)
{
    k1->right = left_left(k1->right);
    return right_right(k1);
}

AvlTree Printf_tree(AvlTree T)
{
    if(T==NULL)return NULL;
    else
    {
        printf("父亲节点是:%d ",T->data);
        printf("左儿子是: ");
        if(T->left==NULL)printf("NULL");
       else printf("%d",T->left->data);
       printf("右儿子是:");
       if(T->right==NULL)printf("NULL");
       else printf("%d",T->right->data);
       printf(" 高度是:%d\n",height(T));
    }
    Printf_tree(T->left);
    Printf_tree(T->right);
}

AvlTree Delete(int x,AvlTree T)
{
    if(T==NULL)return NULL;
    else
    {
        if(T->data==x)
        {
            if(T->right==NULL)
            {
                AvlTree tem = T;
                T = T->left;
                free(tem);
            }
            else
            {
                AvlTree tem = T->right;
                while(tem->left!=NULL)
                {
                    tem = tem->left;
                }
                T->data = tem->data;
                //free(tem);
                //tem=NULL;
                T->right = Delete(T->data,T->right);
                T->Height = max(height(T->left),height(T->right))+1;
            }
            return T;
        }
        else if(x>T->data)
        {
            T->right = Delete(x,T->right);
        }
        else if(x<T->data)
        {
            T->left = Delete(x,T->left);
        }

        //删除后判断是否平衡,不平衡则需旋转
        T->Height = max(height(T->left),height(T->right))+1;
        if(T->left!=NULL)
        {
            T->left = balance(T->left);
        }
        if(T->right!=NULL)
        {
            T->right = balance(T->right);
        }
        if(T!=NULL)
        {
            T = balance(T);
        }
        return T;
    }
}

AvlTree balance(AvlTree T)
{
    if(height(T->left)-height(T->right)==2)
    {
        if(height(T->left->left)>height(T->left->right))
        {
            T = left_left(T);
        }
        else
        {
            T = left_right(T);
        }
    }
    else if(height(T->right)-height(T->left)==2)
    {
        if(height(T->right)-height(T->left))
        {
            T = right_right(T);
        }
        else
        {
            T = right_left(T);
        }
    }
    else
    {
        return T;
    }
}

 

AVL树插入删除

标签:

原文地址:http://www.cnblogs.com/hrcadx/p/5970935.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!