伸展树扩展(splay)过程,代码结合图片讲解

前言:前段时间看了伸展树,没想到一下子又忘记了,然后看了向浅的博客《伸展树c++ 实现》,决定自己也写一点自己理解过程中觉得难的地方!关于理论部分,阅读《伸展树c++ 实现》这篇博客足矣~



先看一个伸展树的例子:


伸展树的splay函数:

  1.    void splay(const Comparable& x, BinaryNode *& root)  
  2.     {  
  3.         static BinaryNode header(x,nullnode,nullnode);  
  4.         BinaryNode * leftTreeMax,*rightTreeMin;  
  5.       
  6.         header.right = header.left = nullnode;   //因为static 语句只会调用一次对象的构造函数,所以必须要在这里清空左右子树  
  7.         leftTreeMax  = rightTreeMin = &header;        
  8.         nullnode->element = x;  

  9.         for(;;)  
  10.         {  
  11.             if(x < root->element)  
  12.             {  
  13.                 BinaryNode * leftChild = root->left;  
  14.                   
  15.                 if(x < leftChild->element)  
  16.                 {  
  17.                     rotateWithLeftChild(root);  // 该函数执行完成后,root 指向p 节点  
  18.                 }  
  19.   
  20.                 if(root->left == nullnode)      
  21.                     break;  
  22.                 rightTreeMin->left = root;  
  23.                 rightTreeMin = root;  
  24.   
  25.                 root = root->left;          
  26.             }  
  27.             else if(x > root->element)  
  28.             {  
  29.                 BinaryNode * rightChild = root->right;  
  30.                 if(x > rightChild->element)  
  31.                 {  
  32.                     rotateWithRightChild(root);       
  33.                 }  
  34.   
  35.                 if(root->right == nullnode)  
  36.                     break;  
  37.   
  38.                 leftTreeMax->right = root;  
  39.                 leftTreeMax = root;  
  40.                   
  41.                 root = root->right;   
  42.             }  
  43.             else  
  44.                 break;  
  45.         }   
  46.         leftTreeMax->right = root->left;  
  47.         rightTreeMin->left = root->right;  
  48.   
  49.         root->left = header.right;  
  50.         root->right = header.left;  
  51.     } 

下面以上面的例子结合图形讲解伸展过程:

  1.                                                          header.right = header.left = nullnode;   
  2.                                                          leftTreeMax  = rightTreeMin = &header; 




  • if(x > root->element)  
  • {  
  •    BinaryNode * rightChild = root->right;  
  •    if(x > rightChild->element)  
  •   {  
  •      rotateWithRightChild(root);       
  •   }  
  •   
  •    if(root->right == nullnode)  
  •         break;  
  •   
  •    leftTreeMax->right = root;  
  •    leftTreeMax = root;  
  •                   
  •    root = root->right;   

  •  

    1.   if(x < root->element)  
    2.   {  
    3.      BinaryNode * leftChild = root->left;  
    4.                   
    5.      if(x < leftChild->element)  
    6.       {  
    7.             rotateWithLeftChild(root);  // 该函数执行完成后,root 指向p 节点  
    8.       }  
    9.   
    10.      if(root->left == nullnode)      
    11.          break;  

    12.       rightTreeMin->left = root;  
    13.       rightTreeMin = root;  
    14.   
    15.       root = root->left;          
    16.  }  

  • if(x > root->element)  

  • {  
  •    BinaryNode * rightChild = root->right;  
  •    if(x > rightChild->element)  
  •   {  
  •      rotateWithRightChild(root);       
  •   }  
  •   
  •    if(root->right == nullnode)  
  •         break;  
  •   
  •    leftTreeMax->right = root;  
  •    leftTreeMax = root;  
  •                   
  •    root = root->right;   





    1.         1:leftTreeMax->right = root->left;  
    2.         2:rightTreeMin->left = root->right;  
    3.   
    4.         3:root->left = header.right;  
    5.         4:root->right = header.left;  




    扩展后树的形状:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值