数据结构之线性结构(一,表结构)
作者:冲出宇宙
时间:2006-10-24
修改:2006-11-3
转载请注明作者。
  作者主要参考了www.answers 上面的资料(因为wikipedia上不去)和部分较新学术论文(一般来自于acm, IEEEspringer),如果有什么疑问,您可以参考以上资料,我会努力的把重要的论文罗列在文章里面。
  本文主要介绍了线性数据结构部分,线性数据的分类来自于wikipedia,见页面:www.answers/topic/list-of-data-structures
线性数据结构的分类
  线性数据结构的分类如下:
.(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)
(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(未知)、jpgDCT压缩)、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 Robert 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)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。