• 高级数据结构实现——自顶向下伸展树


    【0】README

    1) 本文部分内容转自 数据结构与算法分析,旨在理解 高级数据结构实现——自顶向下伸展树 的基础知识; 
    2) 源代码部分思想借鉴了数据结构与算法分析,有一点干货原创代码,for original source code, please visithttps://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter12/p345_topdown_splay_tree 
    3) you can also refer to the link http://www.cnblogs.com/huangxincheng/archive/2012/08/04/2623455.html

    4) for basic splay tree , please visit http://blog.csdn.net/PacosonSWJTU/article/details/50525435


    【1】自顶向下伸展树相关

    1)problem+solution

    • 1.1)problem: 普通伸展树的展开操作需要从根沿树往下的一次遍历, 以及而后的从底向上的一次遍历。(详情,参见:http://blog.csdn.net/pacosonswjtu/article/details/50525435) 这可以通过保存一些父指针来完成, 或者通过将访问路径存储到一个栈中来完成。 但遗憾的 是, 这两种方法均需要大量的开销 ;
    • 1.2)solution: 本节中, 我们指出如何在初始访问路径上施行一些旋转。结果得到在时间中更快的过程,只用到 O(1)的额外空间, 但却保持了 O(logN) 的摊还时间界;(干货——伸展树是基于AVL树的, 在AVL的基础上引入伸展树的目的是保持他的摊还时间界为 O(logN))

    2)对伸展树的自顶向下的旋转操作:(单旋转+一字型旋转+之字型旋转)

    • 2.1)这种伸展方式会把树切成三份,L树,M树,R树,考虑的情况有:单旋转,“一字型”旋转,“之字形”旋转。起初左树(L) 和 右树(R)均为空(NULL); 
      这里写图片描述 
       
      这里写图片描述

    3)看个荔枝:

    • 3.1)splay + deleting opeartions: 

    • 3.2)inserting opeartions: 

    4)source code at a glance

     

    #include "topdown_splay_tree.h" 
    
    // allocate memory for new node.
    Node makeNode(int value)
    {
        Node node;
    
        node = (Node)malloc(sizeof(struct Node));
        if(!node)
        {
            Error("failed makeNode, for out of space !");
            return NULL;
        }
        node->left = NULL;
        node->right = NULL;    
        node->value = value;
        
        return node;
    }
    
    // left left single rotate
    TopDownSplayTree left_left_single_rotate(TopDownSplayTree root)
    {        
        TopDownSplayTree temp;
    
        temp = root; // 1st step
        root = root->left; // 2nd step
        temp->left = root->right; // 3rd step
        root->right = temp; // 4th step
        
        return root;
    }
    
    // right_right_single_rotate
    TopDownSplayTree right_right_single_rotate(TopDownSplayTree root)
    {        
        TopDownSplayTree temp;
    
        temp = root; // 1st step
        root = root->right; // 2nd step
        temp->right = root->left; // 3rd step
        root->left = temp; // 4th step    
    
        return root;
    }
    
    // performing splay operations 
    TopDownSplayTree topdown_splay(int value, TopDownSplayTree middle)
    {
        struct Node plusTree;    
        Node leftTreeMax;    
        Node rightTreeMin;
    
        leftTreeMax = &plusTree;
        rightTreeMin = &plusTree;
    
        while(value != middle->value)
        {   
            if(middle->value < value)  // the new node is greater.
            {     
                if(middle->right == NULL)
                {
                    break;
                }
                else if(middle->right->value < value && middle->right->right)
                {
                    middle = right_right_single_rotate(middle);
                }            
                leftTreeMax->right = middle;
                leftTreeMax = middle;
                middle = middle->right;        
                leftTreeMax->right = NULL;
            }
            
            if(middle->value > value) // the new node is less.
            {        
                if(middle->left == NULL)
                {
                    break;
                }
                else if(middle->left->value > value && middle->left->left)
                {
                    middle = left_left_single_rotate(middle);
                }
                rightTreeMin->left = middle;
                rightTreeMin = middle;
                middle = middle->left;
                rightTreeMin->left = NULL;
            }    
        }
        
        leftTreeMax->right = middle->left;
        rightTreeMin->left = middle->right;
        middle->left = plusTree.right;
        middle->right = plusTree.left;
    
        return middle;
    }
    
    // delete the root of the  TopDownSplayTree
    TopDownSplayTree deleteNode(int value, TopDownSplayTree root)
    {
        TopDownSplayTree newroot;
    
        if(root == NULL) 
        {
            return root;
        }
        else // the splay tree is not null
        {
            root = topdown_splay(value, root);
            if(root->value == value)  // find the node with given value.
            { 
                if(root->left == NULL)
                {
                    newroot = root->right;
                }
                else
                {
                    newroot = root->left;
                    // perform splay again with value towards the left subtree which is not null.
                    newroot = topdown_splay(value, newroot);
                    newroot->right = root->right; 
                }
                free(root);
                root = newroot;
            }        
        }    
        
        return root;
    }
    
    // insert the node with value into the TopDownSplayTree
    TopDownSplayTree insert(int value, TopDownSplayTree root)
    {
        TopDownSplayTree node;
        
        node = makeNode(value);         
        
        if(root == NULL) // the splay tree is null
        {
            return node;
        }
        else // the splay tree is not null
        {
            root = topdown_splay(value, root);
    
            if(root->value > value)  
            {
                node->left = root->left;
                node->right = root;
                root->left = NULL;
                root = node;            
            }
            else if(root->value < value)  
            {
                 node->right = root->right;
                 root->right = NULL;
                 node->left = root;             
                 root = node;
            }
            else            
            {
                return root;
            }
        }    
        
        return root;
    }
    
    // test for insert operation.
    int main1()
    {
        TopDownSplayTree root;    
        int data[] = {5, 11, 23, 10, 17};
        int size = 5;
        int i;
        
        printf("
     === executing insert with {5, 11, 23, 10, 17} in turn.=== 
    ");
        root = NULL;
        for(i=0; i<size; i++)
        {
            root = insert(data[i], root);
            printPreorder(1, root);    
        }         
    
        printf("
     === executing insert with 8 in turn.=== 
    ");
        root = insert(8, root);
        printPreorder(1, root);        
    
        printf("
     === executing insert with 18 in turn.=== 
    ");
        root = insert(18, root);
        printPreorder(1, root);
    
        return 0;
    }
    
    // test for splay operation and deleting operation.
    int main()
    {    
        TopDownSplayTree root;
        TopDownSplayTree temp;
        
        printf("
     ====== test for splaying operation====== 
    ");
        printf("
     === original tree is as follows.=== 
    ");
        root = makeNode(12); // root = 12
        temp = root;
        temp->left = makeNode(5);
        temp->right = makeNode(25);
    
        temp = temp->right;  // root = 25
        temp->left = makeNode(20);
        temp->right = makeNode(30);
    
        temp = temp->left;  // root = 20
        temp->left = makeNode(15);
        temp->right = makeNode(24);
    
        temp = temp->left;  // root = 15
        temp->left = makeNode(13);
        temp->right = makeNode(18);
    
        temp = temp->right;  // root = 18
        temp->left = makeNode(16);    
    
        printPreorder(1, root);
    
        printf("
     === executing splay operation with finding value=19.=== 
    ");
        root = topdown_splay(19, root);
        printPreorder(1, root);     
    
        printf("
     === executing deleting operation with value=15.=== 
    ");
        root = deleteNode(15, root);
        printPreorder(1, root);     
    
    
        return 0;
    }
    
    // analog print node values in the binominal tree, which involves preorder traversal. 
    void printPreorder(int depth, TopDownSplayTree root)
    {            
        int i;
        
        if(root) 
        {        
            for(i = 0; i < depth; i++)
                printf("    ");
            printf("%d
    ", root->value);            
            printPreorder(depth + 1, root->left);                                    
            printPreorder(depth + 1, root->right);
        } 
        else
        {
            for(i = 0; i < depth; i++)
                printf("    ");
            printf("NULL
    ");
        }
    } 

     

     

  • 相关阅读:
    Git 几个常用操作
    Ubuntu16.04安装YouCompleteMe
    常用命令总结
    启动Kernel提示Bad Data CRC
    linux4.15.1编译init/mounts报错
    编译Linux-4.15.1内核时遇到:“error : openssl/bio.h :No such file or folder”
    添加mtdparts引起的问题
    arm-linux-ld:u-boot.lds:1: ignoring invalid character `#' in expression
    smartgit的安装
    ubuntu下安装wine
  • 原文地址:https://www.cnblogs.com/pacoson/p/5170234.html
Copyright © 2020-2023  润新知