2.4.1 有序表的定义

  若线性表中的数据元素相互之间可以比较,并且数据元素在线性表中依值非递减或非递增有序排列,即 (i = 2,3,…,n),则称该线性表为有序表(Ordered List)
  有序表的"有序"特性可以给某些操作带来很大方便,在某些应用问题中,如果用有序表而不是线性表将使算法的时间复杂度下降。
 
 


  严格地说,有序表是另一种数据类型。在有序表类型的定义中需限定数据对象中数据元素所属集合为"有序集",即集合中任意两个元素之间都可以进行比较,并在数据关系中加上 的条件。
 
 
  例2-10 编写算法删除有序顺序表中"多余"的数据元素,即使操作之后的有序顺序表中所有元素的值都不相同。
 
算法2.24
  void purge_OL(SqList &L )
 {
  // 删除有序顺序表L中的冗余元素,即使操作之后的有序顺序表中
  // 只保留操作之前表中所有值都不相同的元素

  k = -1;            // k 指示新表的表尾
  for (i=0; i<L.length-1; ++i) // 顺序考察表中每个元素
  {
   if ( k==-1 || L.elem[k]!=L.elem[i])
   L.elem[++k] = L.elem[i]; // 在新表中不存在和L.elem[i]相同的元素
  } // for
  L.length = k+1;        // 修改表长
 } // purge_OL

  显然,此算法的时间复杂度O (ListLength(L))
   解题分析:
  仍采用例2-6的算法思想,存储结构也相同,所不同的仅是"如何判别在"新表"中是否存在和当前考察的元素相同的元素"。
  由于在有序表中的数据元素是依值从小到大依次排列的,则"相同的"元素必定连续排列在一起,因此,如果"新表"中已存在和当前考察的元素相同的元素,那必定是"新表"中的最后一个元素。由此,不需要在"新表"中从头至尾地查询,而只需要和"新表"中当前最后一个元素比较即可。
 
 例如:(2,2,3,3,3,4,4,5,5,5,5,7)经操作后变成(2,3,4,5,7) 动画
 
  读者可以对算法2.21进行改写,同样可以得到一个时间复杂度为O (Listlength(L)) 的算法,但必须注意,应将当前考察的元素插入在"新表"的表尾,以保持链表的有序性。

  前面已经谈到,例2-6和例2-9是例2-2的算法在不同存储结构上的实现,例2-10则可以看成是对例2-2的同样问题,由于采用了不同的数据结构(有序表),因而有了不同的算法。

  从这个例子可以看到"有序表"优越性。