伸展树介绍 - 使用自顶向下的调整算法

来源:互联网 发布:淘宝助理怎么用啊 编辑:程序博客网 时间:2024/06/05 02:18

伸展树自顶向下的伸展
Node* splaytree_splay(SplayTree tree, Type key)
Node N, *l, *r, *c;
N用来表示存放左树和右树根节点的一个Node,其中N->left存放右树的根节点,N->right存放左树的根节点
l表示右树最小节点,r表示左树最大节点,在伸展的过程中,l和r不断变化,并且通过变化连接了每一轮左右树的最大和和最小节点

每一轮的调整过程:
    如果key < tree->key
        如果tree->left == NULL,结束调整
        如果key < tree->left->key
            右旋
            右旋后如果tree->left == NULL,结束调整
        连接右树
            r->left = tree; 连接
            r = tree; 更新r节点
            tree = tree->left; 更新根节点
    如果key > tree->key
        如果tree->right == NULL,结束调整
        如果key > tree->right->key
            左旋
            左旋后如果tree->right == NULL,结束调整
        连接左树
            l->right = tree; 连接
            l = tree; 更新r节点
            tree = tree->right; 更新根节点
    如果相等,结束调整

伸展结束时
l->right = tree->left; 左树的最大节点的右孩子 = 当前根的左孩子
r->left = tree->right;右树的最小节点的左孩子 = 当前根的右孩子
tree->left = N.right; 连接左树
tree->right = N.left; 连接右树   


参考代码如下:

Node* splaytree_splay(SplayTree tree, Type key){    Node N, *l, *r, *c;    if (tree == NULL)         return tree;    N.left = N.right = NULL;    l = r = &N;    for (;;)    {        if (key < tree->key)        {            if (tree->left == NULL)                break;            if (key < tree->left->key)            {                c = tree->left;                           /* 01, rotate right */                tree->left = c->right;                c->right = tree;                tree = c;                if (tree->left == NULL)                     break;            }            r->left = tree;                               /* 02, link right */            r = tree;            tree = tree->left;        }        else if (key > tree->key)        {            if (tree->right == NULL)                 break;            if (key > tree->right->key)             {                c = tree->right;                          /* 03, rotate left */                tree->right = c->left;                c->left = tree;                tree = c;                if (tree->right == NULL)                     break;            }            l->right = tree;                              /* 04, link left */            l = tree;            tree = tree->right;        }        else        {            break;        }    }    l->right = tree->left;                                /* 05, assemble */    r->left = tree->right;    tree->left = N.right;    tree->right = N.left;    return tree;}


0 0
原创粉丝点击