线性表的类型定义

线性表的类型定义

线性结构是一个数据元素的有序(次序)集

线性结构的基本特征

  1. 集合中必存在唯一的一个“第一元素
  2. 集合中必存在唯一的一个“最后元素
  3. 出最后元素之外,均有唯一的后继
  4. 除第一元素之外,均有唯一的前驱

抽象数据类型线性表的定义

抽象数据类型三要素:数据对象,数据关系,基本操作
数据对象和数据关系表示的是线性表的特征(一个数据元素的有序集,数据元素之间存在的是一个次序的关系)

线性表的定义:

ADT List{
  数据对象:
   D = { a i ∣ a i ∈ E l e m S e t , i = 1 , 2 , … , n , n ≥ 0 a_i\lvert a_i\in{ElemSet,i=1,2,\ldots,n, n\geq0} aiaiElemSeti=1,2,,n,n0}
                    {称n为线性表的表长
                     称n = 0时的线性表为空表 }
  数据关系:
    R 1 = { < a i − 1 , a i > ∣ a i − 1 , a i ∈ D , i = 2 , … n } R_1=\lbrace<a_{i-1},a_i>|a_{i-1},a_i\in D,i=2,\ldots n\rbrace R1={<ai1,ai>ai1,aiD,i=2,n}
{设线性表为( a 1 , a 2 , … a i , … , a n a_1,a_2,\ldots a_i,\ldots,a_n a1,a2,ai,,an),称 i i i a i a_i ai在线性表中的位序}
}

基本操作:

  1. 结构初始化(构造一个空的线性表L,线性表长度为0)
    InitList(&L) //结构初始化操作,构造一个空的线性表L

  2. 销毁结构 DestroyList(&L)
    初始条件:线性表L已经存在
    操作结果:销毁线性表L

  3. 引用型操作(操作不改变线性表结构
    ListEmpty(L) //判空
    ListLength(L) //判断线性表的长度
    PriorElem(L, cur_e, &pre_e) //求一个元素的前驱
    NextElem(L, cur_e, &next_e) //求一个元素的后继
    GetElem(L, i, &e) //取第i个位置上的元素
    LocateElem(L,e, compare()) //返回L中第一个与e满足关系的元素的位序,不存在则返回0
    ListTraverse(L, visit()) //依次对L的每个元素调用visit()

  4. 加工型操作(改变线性表结构)
    ClearList(&L) //将L重置位空表,和初始化操作的区别是有初始条件
    PutElem(L, i, &e) //L中的第i个元素赋值同e的值
    ListInsert(&L, i, e) //在L的第i的元素之前插入新的元素,L的长度增加1
    ListDelete(&L, i, &e) //删除L第i个元素,并用e返回其值,L的长度减1

利用上述定义的线性表,可以完成其他更复杂的操作

例2-1

假设:有两个集合A和B分别用两个线性表LA和LB表示(即:线性表中的数据元素几位集合中的成员,现要求一个新的集合 A = A ∪ B A=A\cup B A=AB
上述问题可演绎为:
扩大线性表LA,将存在于线性表LB中而不存在与线性表LA中的数据元素插入到线性表LA中去

  1. 从线性表LB中依次去除每个数据元素:GetElem(LB, i) ——>e
  2. 依值在线性表LA中进行查访:LocateElem(LA, e, equal())
  3. 若不存在, 则插入之:ListInsert(LA, n+1, e)
void union(List &La, List Lb){
 La_len = ListLength(La);
 lb_len = ListLength(Lb);  //求线性表的长度
 for (i = 1; i<=Lb_len; i++){
   GetElem(Lb, i , e);  //取Lb中的第i个元素赋给e
   if(!LocateElem(La, e, equal()))
     ListInsert(La, ++La_len, e); //La中不存在和e相同的元素,则插入之(先加一,后插入)
 }
}//union

例2-2

已知一个非纯集合B(集合中有相同的元素),试构造一个纯集合A,使A中只包含B中所有值各不相同的数据元素。
有两个策略:

  1. 类似问题一的解题思路,先初始化A,依次从表B中取出元素和A中的元素进行比较,然后插入
  2. 先将表B进行排序,则只需要与A中的最后一个元素进行比较即可
void purge(List&La, List Lb){
  //策略一
  //时间复杂度为O(n2)
  InitList(La);  //设置空的线性表La
  La_len = ListLength(La);
  Lb_len = ListLength(Lb);  //求线性表的长度
  for(i=1; i<=Lb_len; i++){
    GetElem(Lb, i ,e); //从线性表Lb中取第i个元素
    if(!LocateElem(La, e, equal())){  
      ++La_len;
      ListInsert(La, La_len, e);  //元素e插入线性表La
    }//if
  }//for
}//purge
void purge(List &La, List Lb){
  // 策略二
  // 时间复杂度为O(n),排序的时间复杂度为可以做到O(nlogn)
  InitList(La);
  La_len = ListLength(La);
  Lb_len = ListLength(Lb);
  for(i=1; i<=Lb_len; i++){
    GetElem(Lb, i, e)  //取Lb中的第i个元素赋值e
    if(ListEmpty(LA)||!equal(en, e)){  //如果为空,则插入,不为空则比较最后一个值
      ListInsert(La, ++La_len, e);
      en = e;  //插入后让最后一个元素值为新插入的元素
    }
  }
}

例2-3

归并两个“其数据元素按值非递减有序排列(关键字递增序排列,但并非是单调递增)的”线性表LA和LB,求得线性表LC也具有同样特性
L a = ( a 1 , … , a i , … , a n ) La=(a_1,\ldots,a_i,\ldots,a_n) La=(a1,,ai,,an)    L b = ( b 1 , … , b i , … , b n ) Lb=(b_1,\ldots,b_i,\ldots,b_n) Lb=(b1,,bi,,bn)
L c = ( c 1 , … , c i , … , c n + m ) Lc=(c_1,\ldots,c_i,\ldots,c_{n+m}) Lc=(c1,,ci,,cn+m)
C k = k = 1 , 2 , … , m + n C_k= k=1,2,\ldots,m+n Ck=k=1,2,,m+n

  1. 分别从LA 和LB中取得当前元素 a i a_i ai b j b_j bj
  2. a i ≤ b j a_i\leq b_j aibj,则将 a i a_i ai插入到LC中,否则将 b j b_j bj插入到LC中
void MergeList(List La, List Lb, List &Lc){
  // 时间复杂度为线性
  InitList(Lc);
  i = j = 1; k = 0;
  La_len = ListLength(La);
  Lb_len = ListLength(Lb);
  while((i<=La_len)&&(j<=Lb_len)){
    //La和Lb均非空
    GetElem(La,i,ai);
    GetElem(Lb,j,bj);
    if(ai<bj){
      ListInsert(Lc,++k,ai); ++i}
    else {ListInsert(Lc, ++k, bj); ++j}
  }
  while(i<=La_len){
    GetElem(La,i++,ai);
    ListInsert(Lc,++k,ai);
  }
  while(j<=Lb_len){
    GetElem(Lb,j++,bj);
    ListInsert(Lc,++k,bj);
  }
}//merge_list
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值