zoukankan      html  css  js  c++  java
  • Splay伸展树

    伸展树,感觉对我这种菜鸟还是有些吃力,主要也是旋转的时候吧,把要查询的节点旋转到根节点,看网上是有两种方法,一是从上到下,一是从下到上。从上到下,是把树拆分成中树,左树和右树,始终保证目标节点在中树,不断向下把中树的节点添到右树或者左树,直到目标节点为中树的根,再将三树合并起来。另外一种从下到上,旋转操作类似AVL树中的旋转,但是判断好像不是很好写,我写的是从上到下的,另外删除也很巧妙,先把目标节点旋转到根,若此时左子树为空直接删除,否则找到左子树最右的节点当头,利用伸展树的特殊旋转就可以一步删除,太牛叉了,还有就是一个元素和指向它的指针的巧妙运用,真是涨了不少知识啊,,,,

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 
      5 typedef struct _spaly
      6 {
      7     int key;
      8     struct _spaly* left;
      9     struct _spaly* right;
     10 }*Pspaly;
     11 
     12 Pspaly splay(Pspaly tree,int k);
     13 void Destory(Pspaly tree);
     14 void Printf(Pspaly tree);
     15 Pspaly Insert(Pspaly tree,int k);
     16 Pspaly Node(int k);
     17 Pspaly Delete(Pspaly tree,int k);
     18 Pspaly Search(Pspaly tree,int k);
     19 
     20 int main()
     21 {
     22     Pspaly tree=NULL;
     23     tree = Insert(tree,3);
     24     tree = Insert(tree,6);
     25     tree = Insert(tree,1);
     26     tree = Insert(tree,5);
     27     tree = Insert(tree,7);
     28     tree = Insert(tree,0);
     29     tree = Insert(tree,11);
     30     Printf(tree);
     31     printf("
    ");
     32     tree=splay(tree,2);
     33      Printf(tree);
     34      printf("
    ");
     35     // tree = splay(tree,6);
     36      tree = Delete(tree,3);
     37      Printf(tree);
     38       printf("
    ");
     39      tree = splay(tree,11);
     40       Printf(tree);
     41     return 0;
     42 }
     43 
     44 Pspaly Node(int k)
     45 {
     46     Pspaly node = (Pspaly)malloc(sizeof(_spaly));
     47     node->key = k;
     48     node->left = NULL;
     49     node->right = NULL;
     50     return node;
     51 }
     52 
     53 Pspaly Insert(Pspaly tree,int k)
     54 {
     55     Pspaly node = Node(k);
     56     if(tree==NULL)
     57     {
     58         tree = node;
     59         return tree;
     60     }
     61     if(k<tree->key)
     62     {
     63         tree->left = Insert(tree->left,k);
     64     }
     65     else if(k>tree->key)
     66     {
     67         tree->right = Insert(tree->right,k);
     68     }
     69     return tree;
     70 }
     71 
     72 //销毁伸展树
     73 void Destory(Pspaly tree)
     74 {
     75     if(tree==NULL)return;
     76     Destory(tree->left);
     77     Destory(tree->right);
     78     free(tree);
     79 }
     80 
     81 //核心,旋转操作
     82 Pspaly splay(Pspaly tree,int k)
     83 {
     84     Pspaly l,r;
     85     _spaly N;
     86     l = r = &N; //  
     87     while(true)
     88     {
     89         if(k<tree->key)
     90         {
     91             if(tree->left==NULL)
     92                 break;//当目标节点不在树上时,在删除时有大用
     93             if(k<tree->left->key)
     94             {
     95                 Pspaly tem = tree->left;
     96                 tree->left = tem->right;
     97                 tem->right = tree;
     98                 tree = tem;
     99             }
    100             //将节点加到右树
    101             r->left = tree; 
    102             r = tree;
    103             tree = tree->left;
    104         }
    105         else if(k>tree->key)
    106         {
    107             if(tree->right==NULL)break;
    108             if(k>tree->right->key)
    109             {
    110                 Pspaly tem = tree->right;
    111                 tree->right = tem->left;
    112                 tem->left = tree;
    113                 tree = tem;
    114             }
    115             l->right = tree;
    116             l = tree;
    117             tree = tree->right;
    118         }
    119         else
    120         {
    121             break;
    122         }
    123 
    124     }
    125     
    126     //合并三课树
    127         l->right = tree->left;
    128         r->left = tree->right;
    129         tree->left = N.right;
    130         tree->right = N.left;
    131         return tree;
    132 }
    133 
    134 //打印函数
    135 void Printf(Pspaly tree)
    136 {
    137     if(tree==NULL)return;
    138     printf("父亲结点是:%d",tree->key);
    139     printf(" 左儿子是:");
    140     if(tree->left==NULL)printf("NULL");
    141     else printf("%d",tree->left->key);
    142     printf(" 右儿子是:");
    143     if(tree->right==NULL)printf("NULL
    ");
    144     else printf("%d
    ",tree->right->key);
    145     Printf(tree->left);
    146     Printf(tree->right);
    147 }
    148 
    149 Pspaly Delete(Pspaly tree,int k)
    150 {
    151     Pspaly tem;
    152     if(Search(tree,k)==NULL)
    153     {
    154         printf("");
    155         return NULL;
    156     }
    157     tree = splay(tree,k);
    158     if(tree->left==NULL)
    159         return tree->right;
    160     else
    161     {
    162         //将tree->left的最右子树当做根
    163       tem = splay(tree->left,k);
    164       tem->right = tree->right;
    165     }
    166     free(tree);
    167     return tem;
    168 }
    169 
    170 Pspaly Search(Pspaly tree,int k)
    171 {
    172     if(tree==NULL)return NULL;
    173     if(k<tree->key)Search(tree->left,k);
    174     else if(k>tree->key)Search(tree->right,k);
    175     else
    176         return tree;
    177 }
    View Code

    再贴个C++的

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <cstring>
      4 
      5 using namespace std;
      6 
      7 template<class T>
      8 class SplayNode
      9 {
     10 public:
     11     T key;
     12     SplayNode* left;
     13     SplayNode* right;
     14 
     15     SplayNode():left(NULL),right(NULL){}
     16     SplayNode(T value,SplayNode* l,SplayNode* r):key(value),left(l),right(r){}
     17 
     18     /*SplayNode()
     19     {
     20         left  = NULL;
     21         right = NULL;
     22     }
     23     SplayNode(T value,SplayNode* l,SplayNode* r)
     24     {
     25         key = value;
     26         left = l;
     27         right = r;
     28     }*/
     29 };
     30 
     31 template <class T>
     32 class SplayTree
     33 {
     34 private:
     35     SplayNode<T>* mroot;
     36 public:
     37     SplayTree();
     38     ~SplayTree();
     39     SplayNode<T>* splay(SplayNode<T>* tree,T k);
     40     void Destory(SplayNode<T>* tree);
     41     void Printf(SplayNode<T>* tree);
     42     void Insert(T k);
     43     SplayNode<T>* Node(T k);
     44     SplayNode<T>* Delete(SplayNode<T>* tree,T k);
     45     SplayNode<T>* Insert_into(SplayNode<T>* Tree,T k);
     46     SplayNode<T>* Search(T k);
     47     void Printf(SplayTree<T>* tree);
     48     void _printf();
     49 };
     50 
     51 template <class T>
     52 SplayTree<T>::SplayTree()
     53 {
     54     mroot = NULL;
     55 }
     56 
     57 template <class T>
     58 SplayTree<T>::~SplayTree()
     59 {
     60     Destory(mroot);
     61 }
     62 
     63 template <class T>
     64 void SplayTree<T>::Destory(SplayNode<T>* tree)
     65 {
     66     if(tree==NULL)return;
     67     Destory(tree->left);
     68     Destory(tree->right);
     69     delete tree;
     70 }
     71 
     72 template <class T>
     73 SplayNode<T>* SplayTree<T>::Node(T k)
     74 {
     75     SplayNode<T>* node = new SplayNode<T>(k,NULL,NULL);
     76    /* node->key = k;
     77     node->left = NULL;
     78     node->right = NULL;*/
     79     return node;
     80 }
     81 
     82 template <class T>
     83 void SplayTree<T>::Insert(T k)
     84 {
     85     mroot = Insert_into(mroot,k);
     86 }
     87 
     88 template <class T>
     89 void SplayTree<T>::_printf()
     90 {
     91     SplayTree::Printf(mroot);
     92 }
     93 
     94 template <class T>
     95 void SplayTree<T>::Printf(SplayNode<T>* tree)
     96 {
     97     if(tree==NULL)return;
     98     printf("父亲节点是:%d",tree->key);
     99     printf(" 左儿子是:");
    100     if(tree->left==NULL)printf("NULL");
    101     else printf("%d",tree->left->key);
    102     printf(" 右儿子是:");
    103     if(tree->right==NULL)printf("NULL
    ");
    104     else printf("%d
    ",tree->right->key);
    105     Printf(tree->left);
    106     Printf(tree->right);
    107 }
    108 template <class T>
    109 SplayNode<T>* SplayTree<T>::Insert_into(SplayNode<T>* tree,T k)
    110 {
    111     SplayNode<T>* node = SplayTree<T>::Node(k);
    112     if(tree==NULL)
    113     {
    114         tree = node;
    115         return tree;
    116     }
    117     if(k<tree->key)
    118     {
    119         tree->left = Insert_into(tree->left,k);
    120     }
    121     else if(k>tree->key)
    122     {
    123         tree->right = Insert_into(tree->right,k);
    124     }
    125     return tree;
    126 }
    127 
    128 template <class T>
    129 SplayNode<T>* SplayTree<T>::splay(SplayNode<T>* tree,T k)
    130 {
    131     SplayNode<T>  N,*r,*l;
    132     N.left = N.right = NULL;
    133     l = r = &N;
    134     while(true)
    135     {
    136         if(k<tree->key)
    137         {
    138             if(tree->left==NULL)break;
    139             if(k<tree->left->key)
    140             {
    141                 SplayNode<T>* tem = tree->left;
    142                 tree->left = tem->right;
    143                 tem->right = tree;
    144                 tree = tem;
    145             }
    146             r->left = tree;
    147             r = tree;
    148             tree = tree->left;
    149         }
    150         if(k>tree->key)
    151         {
    152             if(tree->right==NULL)break;
    153             if(k>tree->right->key)
    154             {
    155                 SplayNode<T>* tem = tree->right;
    156                 tree->right = tem->left;
    157                 tem->left = tree;
    158                 tree = tem;
    159             }
    160             l->right = tree;
    161             l = tree;
    162             tree = tree->right;
    163         }
    164         else
    165         {
    166             break;
    167         }
    168     }
    169     l->right = tree->left;
    170     r->left = tree->right;
    171     tree->left = N.right;
    172     tree->right = N.left;
    173     return tree;
    174 }
    175 
    176 template <class T>
    177 SplayNode<T>* SplayTree<T>::Search(T k)
    178 {
    179     mroot = SplayTree<T>::splay(mroot,k);
    180 }
    181 int main()
    182 {
    183     SplayTree<int>* tree = new SplayTree<int>();
    184     tree->Insert(3);
    185     tree->Insert(6);
    186     tree->Insert(1);
    187     tree->Insert(5);
    188     tree->Insert(7);
    189     tree->Insert(0);
    190     tree->Insert(11);
    191     tree->_printf();
    192     printf("
    ");
    193     tree->Search(11);
    194     tree->_printf();
    195     return 0;
    196 }
    View Code
  • 相关阅读:
    路径操作OS模块和Path类(全)一篇够用!
    数据可视化:绘图库-Matplotlib
    matplotlib中文显示的问题
    Microsoft Visual C++ 14.0 is required问题解决
    python习题——随机整数生成类
    python——时间模块
    怎么获取10个线程的结果再返回
    集群服务器定时任务,只运行一个定时器的设计
    分布式事务
    分布式数据库---分库分表
  • 原文地址:https://www.cnblogs.com/hrcadx/p/5998703.html
Copyright © 2011-2022 走看看