伸展树(splay tree)

/*
 	author:fish1996 
 	date:2016/03/02
*/

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

//the declaration of splayTree
//recursion and with parent pointer
typedef struct splayTreeNode *splayTree;

struct splayTreeNode 
{
    int data;
    splayTree parent;
    splayTree left;
    splayTree right;
};

splayTree findMax(splayTree t)
{
    if (!t)return NULL;
    while (t->right)t = t->right;
    return t;
}

splayTree leftRotation(splayTree t, splayTree x)
{
    splayTree y;
    y = x->right;
    x->right = y->left;
    if (y->left != NULL) {
        y->left->parent = x;
    }
    y->parent = x->parent;
    if (x->parent == NULL) {
        t = y;
    }
    else if (x == x->parent->left) {
        x->parent->left = y;
    }
    else x->parent->right = y;
    y->left = x;
    x->parent = y;
    return t;
}

splayTree rightRotation(splayTree t, splayTree x)
{
    splayTree y;
    y = x->left;
    x->left = y->right;
    if (y->right != NULL) {
        y->right->parent = x;
    }
    y->parent = x->parent;
    if (x->parent == NULL) {
        t = y;
    }
    else if (x == x->parent->right) {
        x->parent->right = y;
    }
    else x->parent->left = y;
    y->right = x;
    x->parent = y;
    return t;
}

void splay(splayTree t, splayTree root)
{
    if (!t||!root) return;
    splayTree p = t->parent;
    if (!p) return;
    if (p->data == root->data) {
        //zig
        if (p->left&&p->left->data == t->data) {
            root = rightRotation(root, p);
        }
        //zag
        else if (p->right&&p->right->data == t->data) {
            root = leftRotation(root, p);
        }
        return;
    }
    else {
        splayTree pp = t->parent->parent;
        if (!pp)return;
        if (p->left&&p->left->data == t->data) {
            //zigzig
            if (pp->left&&pp->left->data == p->data) {
                root = rightRotation(root, pp);
                root = rightRotation(root, p);
            }
            //zagzig
            else if (pp->right&&pp->right->data == p->data) {
                root = rightRotation(root, p);
                root = leftRotation(root, pp);
            }
            splay(t, root);
        }
        if (p->right&&p->right->data == t->data) {
            //zagzag
            if (pp->right&&pp->right->data == p->data) {
                root = leftRotation(root, pp);
                root = leftRotation(root, p);
            }
            //zigzag
            else if (pp->left&&pp->left->data == p->data) {
                root = leftRotation(root, p);
                root = rightRotation(root, pp);
            }
            splay(t, root);
        }
    }
}

splayTree Find(splayTree t, int x, splayTree root)
{
    if (!t || !root)return NULL;
    if (!t->left&&!t->right || x == t->data) {
        splay(t, root);
        return t;
    }
    else if (x<t->data) {
        return Find(t->left, x, root);
    }
    else if (x>t->data) {
        return Find(t->right, x, root);
    }
    return t;
}

splayTree insert(splayTree t, splayTree parent, int x)
{
    if (!t) {
        t = (splayTree)malloc(sizeof(struct splayTreeNode));
        t->data = x;
        t->parent = parent;
        t->left = NULL, t->right = NULL;
    }
    else if (x<t->data) {
        t->left = insert(t->left, t, x);
    }
    else if (x>t->data) {
        t->right = insert(t->right, t, x);
    }
    return t;
}

splayTree splayFind(splayTree t, int x)
{
    return Find(t, x, t);
}

splayTree splayInsert(splayTree t, int x)
{
    t = insert(t, NULL, x);
    return splayFind(t, x);

}
splayTree splayDelete(splayTree t, int x)
{
    if (!t)return NULL;
    t = splayFind(t, x);
    splayTree p;
    if (!t)return NULL;

    if (t->left) {
        t->left = splayFind(t->left, findMax(t->left)->data);
        t->left->right = t->right;
        if(t->right)t->right->parent = t->left;
        p = t->left;
    }
    else p = t->right;
    if(p)p->parent = NULL;
    free(t);
    return p;
}
 
 

你可能感兴趣的:(伸展树(splay tree))