邓俊辉数据结构学习-8-1-伸展树

高级搜索树--伸展树

对于维护平衡因子,感觉很麻烦,希望抛弃掉平衡因子,使用更加潇洒的模式。

要求:

  1. 对于伸展树来说,也不做过多掌握
  2. 主要明白利用数据的局部性,我们可以实施的新策略

概述

背景知识补充:

数据局部性

  • 刚被访问过得数据很快会被再次访问

因此这一次访问过的节点,极有可能再次被访问, 能够实现这种特性的树就是伸展树--就像自适应链表一样

  • 新的名词: 自适应链表

    • 在某一段时间内,将经常需要访问的元素尽可能的放到链表前面
    • 大概实现:就是将上次访问过的节点移动到链表的前端

电脑缓存会充分利用数据的局部性, 因此电脑往往在使用一段时间后就会变的更顺畅

逐层伸展

现在,我们希望通过某种手段让BST实现诸如自适应链表的功能。该怎么做?

按照惯用逻辑,我们手里只有基本变换这唯一工具。因此我们可以使用我们的基本变换将目标节点一步一步地

往上爬,上升到根的位置。

可惜的是,这种方法在最坏情况下分摊复杂度为O(N)意味着等同线性序列,不能接受。

双层伸展

双层伸展通过改变zig-zig和zag-zag的方式实现画龙点睛的作用,让伸展树在伸展的时候会折叠路径,因此,

在经过最坏情况下的一次查找之后,新的伸展树高度会减半。从而分摊时间复杂度达到O(logN)。

具体变换如图所示

经过俩次zigzig变换, 需要注意的是我们要先从g,即祖父节点开始变换,然后才开始在p变换
                 .─.                                               .─.
                ( g )                                             ( v )
                 `─‘?                                             ?`─‘?
                ?    ?                                           ?     ?
            .─.?      ?                  .─.                    ?       ?.─.
           ( p )       ■                ( p )                   ■       ( p )
            `─‘?      ■ ■              ? `─‘ ?                 ■ ■       ?─‘?
           ?    ?    ■T3 ■           ?         ?              ■T0 ■     ?    ?
       .─.?      ?  ■■■■■■■     .─.?             ? .─.       ■■■■■■■   ?      ?.─.
      ( v )       ■            ( v )              ( g )                ■      ( g )
      ?`─‘?      ■ ■           ?`─‘?              ?`─‘?               ■ ■     ?`─‘?
     ?     ?    ■T2 ■         ?     ?            ?     ?             ■T1 ■   ?     ?
    ?       ?  ■■■■■■■       ?       ?          ?       ?           ■■■■■■■ ?       ?
   ■         ■              ■         ■        ■         ■                 ■         ■
  ■ ■       ■ ■            ■ ■       ■ ■      ■ ■       ■ ■               ■ ■       ■ ■
 ■T0 ■     ■T1 ■          ■T0 ■     ■T1 ■    ■T2 ■     ■T3 ■             ■T2 ■     ■T3 ■
■■■■■■■   ■■■■■■■        ■■■■■■■   ■■■■■■■  ■■■■■■■   ■■■■■■■           ■■■■■■■   ■■■■■■■
根据图可以看出,v的左树没有发生变化,g的右树也没有发生变化

zag-zig的情况变换还和之前一样
          .─.                            .─.
         ( g )                          ( g )
          `─‘?                           `─‘?
         ?    ?                         ?    ?                       .─.
     .─.?      ■                    .─.?      ■                     ( v )
    ( p )     ■ ■                  ( v )     ■ ■                    ?`─‘?
     `─‘?    ■T3 ■                  ?─‘?    ■T3 ■                 ?       ?
    ?    ?  ■■■■■■■                ?    ?  ■■■■■■■              ?           ? .─.
   ?      ?─.                  .─.?      ?■                  .─.             ( g )
   ■     ( v )                ( p )      ■ ■                ( p )            ?`─‘?
  ■ ■    ?`─‘?                ?`─‘?     ■T1 ■               ?`─‘?           ?     ?
 ■T2 ■  ?     ?              ?     ?   ■■■■■■■             ?     ?         ?       ?
■■■■■■■?       ■            ■       ?                     ?       ?        ■        ■
      ■ ■     ■ ■          ■ ■      ■                     ■       ■       ■ ■      ■ ■
     ■T0 ■   ■T1 ■        ■T2 ■    ■ ■                   ■ ■     ■ ■     ■T1 ■    ■T3 ■
    ■■■■■■■ ■■■■■■■      ■■■■■■■  ■T0 ■                 ■T2 ■   ■T0 ■   ■■■■■■■  ■■■■■■■
                                 ■■■■■■■               ■■■■■■■ ■■■■■■■

有关splay还需要注意的一个地方是编程问题,就是树的深度为偶数或者奇数的时候会有点小小的不一样。

这个我们假设3,4个节点就可以具体解决。

综合评价

  • 无需判断平衡因子,因此也无需记录高度,编程方便了一些
  • 操作的时间复杂度和AVL一样
  • 最强优点: 在数据局部性强的时候,经过一定使用时间后,使用伸展树可以达到O(logK)的时间复杂度
  • 缺点: 在单次敏感的场合不适合使用

原文地址:https://www.cnblogs.com/patientcat/p/9720322.html

时间: 2024-10-25 15:49:55

邓俊辉数据结构学习-8-1-伸展树的相关文章

邓俊辉数据结构学习-8-2-B树

B树 概述 动机: B树实现高速I/O 640K如何"满足"任何实际需求了-- 源自比尔·盖茨的一个笑话 前提知识 高速缓存 为什么高速缓存有效? 不同容量的存储器,访问速度差异悬殊,磁盘和内存访问速度的量级相差$>10^5$ 如果将访问内存比喻为1秒,那么访问外存则相当于1天 因此我们需要尽量减少IO次数 分级I/O 俩个相邻存储级别之间的数据传输,统称为IO操作 CPU -> RAM -> DISK -> ARRAY 访问速度依次递减,存储容量依次递增 常用

清华大学邓俊辉老师的数据结构在线课程

前几天想重新把数据结构学一遍,于是乎,翻出以前上数据结构的课件,orz...知识遗忘的速度太快了,想找个视频跟着看.令我意想不到的是,我居然能搜索到清华大学邓俊辉老师的数据结构课程,当时把我激动的啊,我要感谢互联网让教育变得那么open.能让我这个二本学校的学生听清华老师的课程,这真的是一件很幸福很幸福的事情. 一流的学校的教育方式就是那么高大上,用OJ提交作业,系统对代码进行黑盒测试...这个课程一直持续到来年1.5日才结束.这么好的资源一定要和大家分享:http://www.xuetangx

Coursera 数据结构 清华 邓俊辉 第十二章 漫谈快排

引言 ? ? 本文从多个方面讲解了快速排序的知识点,包括快排分而治之的思想,以及他与归并排序注重点的不同,快排的性能,包括最优最差以及平均性能,并以均匀分布为例,证明了快排的平均性能是1.39*(n+1)logn,接下来又从熵的角度说明了一下快排为什么下界只能达到nlogn,为什么堆排比快排慢,而基排又能够逃脱nlogn的界限,因为nlogn只针对基于比较的排序算法 ? ? 快排的思想 ? ? 快排采取分而治之的思想,将待排序的序列分为两个子序列S分为SL和SR两个子序列,这个思想跟归并排序有点

《数据结构:邓俊辉版》——冒泡排序

1.思路 每次都是相邻两个数之间进行比较: 每轮比较之后总是把最大的数或者最小的数筛选出来. 2.源码 #include <memory> void BubbleSort(int szArray[], int nLen); void main() { int szArray[] = {6,4,8,1,9,13}; BubbleSort(szArray, _countof(szArray)); getchar(); } void BubbleSort(int szArray[], int nLe

《数据结构:邓俊辉版》——并归排序

void MergeSort(int low, int high) { int mid = (low + high) / 2; if (high - low < 1) { return; } MergeSort(low, mid); MergeSort(mid + 1, high); Merge(low, mid, high); } void Merge(int low, int mid, int high) { int* A = g_szArray + low; int llen = mid

《数据结构:邓俊辉版》——交换排序

void SelectSort(int nLen) { for (int i = 0; i < nLen; i++) { int j = i; int nMax = i; while (j < nLen) { if (g_szArray[j] > g_szArray[nMax]) { nMax = j; } j++; } int tmp = g_szArray[i]; g_szArray[i] = g_szArray[nMax]; g_szArray[nMax] = tmp; } } 原

《数据结构:邓俊辉版》——插入排序

void InsertSort(int nLen) { for (int i = 1; i < nLen; i++) { int j = i - 1; while (g_szArray[j] > g_szArray[i]) { j--; if (j < 0) { break; } } if (j == i - 1) { continue; } int tmp = g_szArray[i]; int k = i; while (k > j) { g_szArray[k] = g_sz

树结构的自定义及基本算法(Java数据结构学习笔记)

数据结构可以归类两大类型:线性结构与非线性结构,本文的内容关于非线性结构:树的基本定义及相关算法.关于树的一些基本概念定义可参考:维基百科 树的ADT模型: 根据树的定义,每个节点的后代均构成一棵树树,称为子树.因此从数据类型来讲,树.子树.树节点是等同地位,可将其看作为一个节点,用通类:Tree表示.如下图所示: 图:Tree ADT模型示意图 可采用"父亲-儿子-兄弟"模型来表示树的ADT.如图所示,除数据项外,分别用三个引用表示指向该节点的父亲,儿子,兄弟. 图:"父亲

Splay Tree(伸展树)

参考:<数据结构(C++语言版)>邓俊辉著 (好书 一. 伸展树(由 D. D. Sleator 和 R. E. Tarjan 于 1985 年发明)也是平衡二叉搜索树的一种形式.相对于 AVL 树,伸展树的实现更为简洁 伸展树无需时刻都严格地保持全树的平衡,但却能够在任何足够长的真实操作序列中,保持分摊意义上的高效率 伸展树也不需要对基本的二叉树节点结构做任何附加的要求或改动,更不需要记录平衡因子或高度之类的额外信息,故适用范围更广 二.局部性 信息处理的典型模式是,将所有的数据项视作一个集