数据结构(七)之树

二叉查找树查找插入和删除的时间复杂度都为O(log N)。但它有个弊端。

假设输入的数据是排序数据。那么代价巨大,由于树将仅仅由那么没有左(或右)儿子的节点组成。

一种解决方法是找平衡条件:不论什么节点的深度不能过深。最老的一种平衡查找树。即AVL树。另外,较新的方法是放弃平衡条件,同意树有不论什么的深度,可是在每次操作之后要使用一个调整规则进行调整。使得后面的操作效率更高,这是自调整类结构,比如伸展树。

1. AVL树

AVL树是每一个节点的左子树和右子树的高度最多差1的二叉查找树。除去可能的插入外,全部的树查找都能够以时间O(log N)运行。插入一个节点要靠旋转来修正:旋转有两种情况。一是插入发生在“外边的情况”,通过单旋转来调整。

二是发生在“内部”的情形。通过“双旋转”来实现。除旋转引起的局部变化外。编程人员必须记住:树的其它部分必须知晓该变化。

对AVL树的删除多少要比插入复杂,假设删除操作相对较少,那么懒惰删除恐怕是最好的策略。

2. 伸展树

伸展树的基本想法是。当一个节点被訪问后,它就要经过一系列AVL树的旋转被放到根上。另外,伸展树还不要求保留高度或平衡信息。

保证从空树開始随意连续M次对树的操作最多花费O(Mlog N)的时间。

展开思路:从底部向上沿着訪问路径旋转。假设X的父节点是树根。那么我们仅仅要旋转X和树根。这是最后的旋转。

假设出现之字型。则像AVL那样双旋转。假设出现一字型。则将左边的树变换成右边树。

我们能够通过訪问要删除的节点实行删除操作。将节点推到根处,然后找到左子树中最大的元素然后旋转到左子树下。此时的左子树没有右儿子,我们将能够使右子树称为右儿子从而结束删除。对于伸展树分析非常困难。但编程要比AVL树简单得多。这是由于要考虑得情形少许而且没有平衡信息须要存储。

3. B树

迄今为止,我们始终如果能够把整个数据结构存储到计算机的主存中。但是,如果数据太多主存装不下,那么就意味着必须把数据结构放在磁盘上。此时,由于大O模型不再使用。所以导致规则发生了变化。

一棵M叉查找树能够有M路分支,随着分支添加,树的深度在降低。一颗全然M叉树的高度约为logMN

B树是平衡M-路树,是经常使用的查找树。

阶为M的B-树定义:

> 数据项存储在树叶上
> 非叶节点存储直到M-1个键,以指示搜索的方向。键i代表子树i+1中得知最小的键
> 树的根或者是一片树叶,或者其儿子数在2到M之间
> 除根外。全部非树叶节点的儿子数在[M/2]到M之间
> 全部的树叶都在同样的深度上并有[L/2]和L之间个数据项

L=5时。

4阶B-树称为2-3-4树。3阶B-树叫做2-3树。

B-树的深度最多是[logM/2N]。我们运行O(log
M)时间的工作量以确定选择哪个分支(使用折半查找),可是Insert和Delete运算可能须要O(M)的工作量来调整该节点该节点上的全部信息。因此。对于每一个Insert和Delete,最坏情形的执行时间为O(MlogMN)=O((M/logM)logN)。只是,对于一次Find仅仅花费O(log
N)的时间。

经验指出,从执行时间考虑,M的最好选择是M=3或4。

B-树实际用于数据库系统。在那里树被存储在物理的磁盘上而不是主存中。一般来说,对磁盘的訪问要比不论什么的主存操作慢几个数量级。假设我们使用M-阶B-树。那么磁盘訪问次数是O(logMN)。

尽管每次磁盘訪问花费O(logM)来确定分支的方向,可是运行该操作的时间一般比读存储器的区块所花费的时间少得多。

总结

我们已经看到树在操作系统、编译器设计以及查找中的应用。表达式树是更一般结构即所谓的分析树的一个小样例,分析树是编译器设计中的核心数据结构。查找树在算法设计中是很重要的。它们差点儿支持全部实用的操作。查找树的非递归实现多少要快一些。可是递归实现更讲究、更精彩。并且易于理解和除错。查找树的问题在于。其性能严重的依赖于输入,而输入则是随机的。

不改变树的操作都能够使用标准二叉查找树的程序。改变树的操作必须将树恢复。

在伸展树中的节点能够达到随意深度,可是在每次訪问之后树又以多少有些神奇的方式被调整。随意连续M次操作花费O(M
log N)的时间。它与平衡树花费的时间同样。B-树是平衡M-路树,它能非常好的匹配磁盘。其特殊情形是2-3树,它是实现平衡查找树的还有一种经常用法。

在实践中,全部平衡树方案的执行时间都不如简单二叉查找树省时。

时间: 2024-08-26 07:33:50

数据结构(七)之树的相关文章

浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的时候具有较高的灵活性,而有序数组在查找时具有较高的效率,本文介绍的二叉查找树(Binary Search Tree,BST)这一数据结构综合了以上两种数据结构的优点. 二叉查找树具有很高的灵活性,对其优化可以生成平衡二叉树,红黑树等高效的查找和插入数据结构,后文会一一介绍. 一 定义 二叉查找树(B

【经典数据结构】B树与B+树

本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据.对其进行排序并允许以O(log n)的时间复杂度运行进行查找.顺序读取.插入和删除的数据结构.B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树.与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作.B-tree算法减少定位记录时

数据结构之AVL树

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 在前面的博文中,我们已经介绍了数据结构之二分查找树的相关知识,二分查找的提出主要是为了提高数据的查找效率.同一个元素集合可以对应不同的二分查找树BST,二分查找树的形态依赖于元素的插入顺序.同时我们也已经知道,如果将一个有序的数据集依次插入到二查找树中,此时二分查找树将退化为线性表,此时查找的时间复杂度为o(n).为了防止这一问题的出现,便有了平衡二叉树的存在价值.平衡二叉树从根本上将是为了防止出现斜二叉树的出现,从而进一步提高元素的查找效率,

【数据结构】Trie树

1.Trie树简介 Trie树,又称字典树.前缀树,被用于信息检索(information retrieval)的数据结构.Trie一词便来自于单词retrieval.基本思想:用字符串的公共前缀降低查询时间.比如,在最优的查询二叉树中查询关键字的时间复杂度为M * log N,M是字符串最大长度,N为字符串数量:而用Trie树时,只需O(M)时间. [1] 中给出一个简单Trie树例子,蓝色表示一个单词结尾:该Trie树存储的单词为the, their, there, a, any, answ

D&F学数据结构系列——B树(B-树和B+树)介绍

B树 定义:一棵B树T是具有如下性质的有根树: 1)每个节点X有以下域: a)n[x],当前存储在X节点中的关键字数, b)n[x]个关键字本身,以非降序存放,因此key1[x]<=key2[x]<=...<=keyn[x][x], c)leaf[x],是一个布尔值,如果x是叶子的话,则它为TRUE,如果x为一个内节点,则为FALSE. 2)每个内节点包含n[x]+1个指向其子女的指针c1[x],c2[x],...,cn[x]+1[x].叶节点没有子女,故它们的ci域无意义. 3)各关键

《数据结构》线段树入门(二)

今天继续介绍——线段树之延迟标记 接上期<数据结构>线段树入门(一):http://www.cnblogs.com/shadowland/p/5870339.html 在上期介绍了线段树的最基本内容(线段树单点修改,区间查询),这次将介绍:区间修改,区间查询. Question: 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述: 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,每行表示操作的个数,如果第一数是1,后接3个正

可持久化数据结构之主席树

转自:http://finaltheory.info/?p=249 HomeACM可持久化数据结构之主席树 06十2013 可持久化数据结构之主席树 Written by FinalTheory on. Posted in ACM 引言 首先引入CLJ论文中的定义: 所谓的“持久化数据结构”,就是保存这个数据结构的所有历史版本,同时利用它们之间的共用数据减少时间和空间的消耗. 本文主要讨论两种可持久化线段树的算法思想.具体实现以及编码技巧. 核心思想 可持久化线段树是利用函数式编程的思想,对记录

《ACM/ICPC 算法训练教程》读书笔记 之 数据结构(线段树详解)

依然延续第一篇读书笔记,这一篇是基于<ACM/ICPC 算法训练教程>上关于线段树的讲解的总结和修改(这本书在线段树这里Error非常多),但是总体来说这本书关于具体算法的讲解和案例都是不错的. 线段树简介 这是一种二叉搜索树,类似于区间树,是一种描述线段的树形数据结构,也是ACMer必学的一种数据结构,主要用于查询对一段数据的处理和存储查询,对时间度的优化也是较为明显的,优化后的时间复杂为O(logN).此外,线段树还可以拓展为点树,ZWK线段树等等,与此类似的还有树状数组等等. 例如:要将

【经典数据结构】B树与B+树(转)

本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为"在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据.对其进行排序并允许以O(log n)的时间复杂度运行进行查找.顺序读取.插入和删除的数据结构.B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树.与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作.B-tree算法减少定位记录时

【数据结构】Huffman树

参照书上写的Huffman树的代码 结构用的是线性存储的结构 不是二叉链表 里面要用到查找最小和第二小 理论上锦标赛法比较好 但是实现好麻烦啊 考虑到数据量不是很大 就直接用比较笨的先找最小 去掉最小再找第二小的方法了. #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct{ unsigned int weight; unsigned int parent, lchild, r