算法:伸展树的实现

splaytree.h

#ifndef _SPLAYTREE_H
#define _SPLAYTREE_H

struct Node;
typedef int ElementType;
typedef struct Node *PtrToNode;
typedef PtrToNode SplayTree;
typedef PtrToNode Position;

SplayTree MakeEmpty(SplayTree T);
Position Find(ElementType X,SplayTree T);
Position FindMax(SplayTree T);
Position FindMin(SplayTree T);
SplayTree Insert(ElementType X,SplayTree T);
SplayTree Delete(ElementType X,SplayTree T);

#endif

struct Node
{
    ElementType element;
    PtrToNode Left;
    PtrToNode Right;
    PtrToNode Parent;
};

splaytree.c

#include <stdlib.h>
#include <stdio.h>
#include "SplayTree.h"

SplayTree MakeEmpty(SplayTree T)
{
    if(T!=NULL){
        MakeEmpty(T->Left);
        MakeEmpty(T->Right);
        free(T);
    }
    return NULL;
}
Position Find_value(ElementType X,SplayTree T)
{
    if(T==NULL){
        return NULL;
    }else if(X<T->element){
        return Find_value(X,T->Left);
    }else if(X>T->element){
        return Find_value(X,T->Right);
    }
    return T;
}
SplayTree SingleRotateWithLeft(SplayTree T)
{
    Position P=T->Left,Parent=T->Parent;
    T->Left=P->Right;
    P->Right=T;
    P->Parent=Parent;
    T->Parent=P;
    if(Parent!=NULL){
        if(Parent->Left==T){
            Parent->Left=P;
        }else if(Parent->Right==T){
            Parent->Right=P;
        }
    }
    return P;
}
SplayTree SingleRotateWithRight(SplayTree T)
{
    Position P=T->Right,Parent=T->Parent;
    T->Right=P->Left;
    P->Left=T;
    P->Parent=Parent;
    T->Parent=P;
    if(Parent!=NULL){
        if(Parent->Left==T){
            Parent->Left=P;
        }else if(Parent->Right==T){
            Parent->Right=P;
        }
    }
    return P;
}
SplayTree DoubleRotateWithLeft(SplayTree T)
{
    SingleRotateWithRight(T->Left);
    return SingleRotateWithLeft(T);
}
SplayTree DoubleRotateWithRight(SplayTree T)
{
    SingleRotateWithLeft(T->Right);
    return SingleRotateWithRight(T);
}
void Rotate_Zig_Zig(SplayTree T)
{
    Position P;
    P=SingleRotateWithLeft(T);
    SigleRotateWithLeft(P);
}
void Rotate_Zag_Zag(SplayTree T)
{
    Position P;
    P=SingleRotateWithRight(T);
    SingleRotateWithRight(P);
}
void Rotate_With_GrandPa(SplayTree T,Position P)
{
    Position Parent=P->Parent,GrandPa=P->Parent->Parent;
    if(GrandPa->Left==Parent){
        if(Parent->Left==P){
            Rotate_Zig_Zig(GrandPa);
        }else if(Parent->Right==P){
            DoubleRotateWithLeft(GrandPa);
        }
    }else if(GrandPa->Right==Parent){
        if(Parent->Left==P){
            DoubleRotateWithRight(GrandPa);
        }else if(Parent->Right==P){
            Rotate_Zag_Zag(GrandPa);
        }
    }
}
SplayTree Splay_Tree(SplayTree T,Position P)
{
    while(T->Left!=P&&T->Right!=P){
        Rotate_With_GrandPa(T,P);
    }
    if(T->Left==P){
        return SingleRotateWithLeft(T);
    }else{
        return SingleRotateWithRight(T);
    }
}
Position Find(ElementType X,SplayTree T)
{
    Position P;
    P=Find_value(X,T);
    if(P!=NULL&&P->Parent!=T){
        Splay_Tree(T,P);
    }
    return P;
}
SplayTree Insert(ElementType X,SplayTree T)
{
    Position temp;
    if(T==NULL){
        T=malloc(sizeof(struct Node));
        if(T==NULL){
            printf("out of space");
            exit(1);
        }else{
            T->Left=T->Right=T->Parent=NULL;
        }
    }else if(X<T->element){
        temp=Insert(X,T->Left);
        temp->Parent=T;
        T->Left=temp;
    }else if(X>T->element){
        temp=Insert(X,T->Right);
        temp->Parent=T;
        T->Right=temp;
    }
    return T;
}
SplayTree Delete(ElementType X,SplayTree T)
{
    Position P,temp;
    P=Find(X,T);
    if(P!=NULL){
        if(P->Left==NULL&&P->Right==NULL){
            free(P);
            return NULL;
        }else if(P->Left==NULL){
            temp=P->Right;
            free(P);
            return temp;
        }else if(P->Right==NULL){
            temp=P->Left;
            free(P);
            return temp;
        }else{
            temp=FindMin(P->Right);
            P->element=temp->element;
            temp->Parent->Left=NULL;
            free(temp);
            return P;
        }
    }
    return NULL;
}

 

转载于:https://www.cnblogs.com/peixiguang/p/6536297.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值