数据结构之线性结构

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构之线性结构(一,表结构)

作者:冲出宇宙

时间:2006-10-24

修改:2006-11-3

转载请注明作者。

作者主要参考了上面的资料(因为wikipedia上不去)和部分较新学术论文(一般来自于acm, IEEE和springer),如果有什么疑问,您可以参考以上资料,我会努力的把重要的论文罗列在文章里面。

本文主要介绍了线性数据结构部分,线性数据的分类来自于wikipedia,见页面:/topic/list-of-data-structures。

1 线性数据结构的分类

线性数据结构的分类如下:

.表(List)

.数组(Array)

.位图(Bitmaps)

.图片(Images)

.数字高程模型(Heightfield)

.动态数组(Dynamic array)

.平行数组(Parallel array)

.向量(Vector)

.集合(Set)

.链表(Linked list)

.松散链表(Unrolled linked list)

.Xor链表(Xor linked list)

.可变表(VList)

.联合数组(Associative array)

.散列表(Hash table)

.跳跃表(Skip list)

.栈(Stack)

.队列(Queue)

.优先队列(Priority queue)

.双向队列(Deque)

.间隙缓冲(Gap buffer)

2 表(List)

表是一个抽象数据结构(ADT, abstract data type,它表示的是一种接口,而不是实现),它表示的是一个有序实体集合。但是,表并没有一个确定的接口。比如,可变的表会包含4种操作:

1,建立空表;

2,测试表十分为空;

3,在前端插入一个数据到表里面去;

4,返回一个新表,包含了除了第一个元素(也可能是最后一个元素)以外的其它所有元素。

在现实中,表通常由数组或者链表实现,因为它们都和表具有一些共同点。通常人们会把表当成是链表的别名。序列也是表的另外一个名字,它突出了实体之间的顺序关系。

2.1 数组(Array)

和数组相关的有向量、表(一维数组实现)、矩阵(二维数组实现),数组是一种最简单的数据结构。数组包含了一系列的数据元素,而且这些元素一般都是同样的大小和类型。数组里面的元素通过索引来访问,一般的说,索引是一段连续的整数范围,但是,它也可以为任何有序的数值。数组可以是多维的,比如,2维数组。3维或者以上的数组很少被采用。

时间复杂度:

通过索引访问数组极快(o(1)),但是,从数组里面插入或者删除一个数据的代价很高(o(n)),特别是删除数据可能会造成数组空闲太多,和插入数据造成数组空间不够。这些可以利用动态数组来解决。链表虽然插入或者删除数据较快,可是访问其中的元素十分慢(o(n))。

空间复杂度:

数组是最不浪费内存的数据结构,比较起来散列表是十分浪费内存的。数组不占用任何额外的空间(最多增加一个保存数组的大小,4字节)。

程序:

大部分程序都内置数组类型。

2.1.1 位图(Bitmap)

位图其实是一个数组,数组的每个元素都是布尔值(0/1)。常常使用字节数组来表示位图,因为每个字节可以表示8个位图的元素。位图最常用在空间处理上,比如,磁盘分配。根据位图的个性,所有用来表示是和否的地方都可以使用它。因为一个字节的位图可以表示8个是和否,所以,它也常常用来压缩数据。不过,访问一位比访问一个字节会慢很多,访问一个字节比访问一个int会慢很多(如果32位机器)。

2.1.1.1 图片(Images)

图片也叫数字图片。图片是一个2维结构,每个元素对应于图片上的某点。每个元素的大小根据其要显示的效果而变化,主要有1位,8位,16位,24位,32位几种。根据显示色彩的不同,一般可以分为黑白、灰度、彩色(8位,16位,24位,32位)、抖动色这几种。一般的图片都由很多像素组成,所以,一个图片占用的空间十分大。一般情况下,压缩是必须的。最常见的几种压缩格式为:gif(lzw压缩)、png(未知)、jpg(DCT压缩)、jpg2000(小波压缩)。

2.1.1.2 数字高程模型(Heightfield 也叫:Digital Elevation Model, or DEM)

DEM也是一个位图,只是,它每个点表示的意思是高度。

上图是根据dem图还原出来的火星地图。下图是一个加上了色彩的DEM 图。

2.1.2 动态数组(Dynamic Array)

它同时的名字还有:可增数组(growable array), 可变长数组(resizable array), 动态表(dynamic table), 数组表(array list)。它是一种能够自动调整自己大小的数组。

当加入一个新数据时,如果动态数组没有空间了,它会申请一个新的空间,然后把旧数据全部拷贝过去,释放旧空间(有些动态数组的实现并不会拷贝旧数据过去,也不会释放旧空间)。一般的时候,新分配的空间大小都是原来空间大小的一个倍数,保证有一部分空间是空闲的。简单的计算一下,就能发现加入一个数据的平均花销是o(1)。同样的道理,删除一个数据的时候,如果空闲的空间太多了,动态数组也可能申请一个新空间,然后删除旧空间。

申请新空间时,申请多大的空间是一个值得考虑的问题。目前来说,一般认为申请的新空间为旧空间的1.4-4倍之间都是合适的,最常见的是2倍。

在浪费空间上面,有人证明了至少需要浪费o(n^1/2)这么多空间才能保证插入和删除都在常数时间内完成。

Andrej Brodnik, Svante Carlsson, Erik D. Demaine, J. Ian Munro, and R obert Sedgewick. Resizable Arrays in Optimal Time and Space (1999). Workshop on Algorithms and Data Structures, pp.37–48

动态数组还有很多变形,比如,为了加快删除的速度,可以把开始的数据放到中间(如图):

这里,第一个数据放到数组的中间,第i个数据放到(i+n/2)%n的位置。当删除数据的时候,最多只需要移动n/2次就行了。当然了,需要保存一个开始的位置和实际的数组长度。比如,删除掉3,得到:5 6 7 1 2 4 *,删除掉7得到:* 5 6 1 2 4 *。

2.1.3 平行数组(Parallel Array)

平行数组最初是为了在不支持记录(对象)的环境下面使用的。它把一个记录切分成多个基本数组,每个数组的长度一样。比如,

struct Info{

相关文档
最新文档