第二章——线性表

线性表

线性结构的特点

在数据元素的有限集合中:
存在唯一的一个被称作“第一个”的数据元素
存在唯一的一个被称作“最后一个”的数据元素
除第一个外,集合中的每个数据元素均只有一个前驱
除最后一个外,集合中的每个数据元素均只有一个后继

线性表的类型定义

一、定义
一个线性表是n个数据元素的有限序列
二、抽象数据类型的定义
(一)、具体操作
1、初始化操作Initlist(&L)
2、结构销毁操作DestroyList( &L )
3、引用型操作
ListEmpty( L )线性表判空
ListLength( L )求线性表长度
PriorElem( L, cur_e, &pre_e )(求数据元素的前驱)
NextElem( L, cur_e, &next_e )(求数据元素的后继)
GetElem( L, i, &e )(求线性表中某个数据元素)
LocateElem( L, e, compare( ) )(定位函数)
ListTraverse(L, visit( ))(遍历线性表)
4、加工型操作
ClearList( &L )(将存在的线性表置空)
ListInsert( &L, i, e )(在i之前插入数据元素e)
ListDelete(&L, i, &e)(删除L的第i个数据元素,并用e返回其值)
(二)
1、线性表中元素的个数n(n>=0)定义为线性表的长度,n=0时称为空表。ai是第i个数据元素,称i为ai在线性表中的位序。
2、有序表
若线性表中的数据元素相互之间可以比较,并且数据元素在线性表中依值非递减或非递增有序排列,即
ai≥ai-1 或 ai≤ai-1(i = 2,3,…, n),
则称该线性表为有序表(Ordered List)。
3、例题:设 La = (a1, …, ai, …, an), Lb = (b1, …, bj, …, bm)
Lc = (c1, …, ck, …, cm+n)
且已由(a1, …, ai-1)和(b1, …,bj-1)归并得 (c1, …, ck-1)
取ai与bi中的最小值复值给Ck

void MergeList(List La, List Lb, List &Lc) {
  // 本算法将非递减的有序表 La 和 Lb 归并为 Lc
  InitList(Lc);  // 构造空的线性表 Lc
i = j = 1;    k = 0;
La_len = ListLength(La);
Lb_len = ListLength(Lb);
while ((i <= La_len) && (j <= Lb_len)){
 GetElem(La, i, ai);    
 GetElem(Lb, j, bj);
 if (ai <= bj) {  // 将 ai 插入到 Lc 中
    ListInsert(Lc, ++k, ai);  ++i; }
else {   // 将 bj 插入到 Lc 中
    ListInsert(Lc, ++k, bj);  ++j; }
}// La 和 Lb 均不空 
while (i<=La_len) {
      GetElem(La, i++, ai);   
         ListInsert(Lc, ++k, ai);
}  // 若 La 不空
while (j<=Lb_len) {
GetElem(Lb, j++, bj);
         ListInsert(Lc, ++k, bj);
} // 若 Lb 不空
线性表的类型实现

一、顺序映像
(一)基本内容
1、用一组地址连续的存储单元依次存放线性表中的数据元素。
2、一般来说,线性表的第i个数据元素ai的存储位置为
LOC(ai) = LOC(a1) + (i-1)×C
LOC(a1)为↑基地址
3、是一种随机存取的存储结构
4、时间复杂度为O(n)
(二)线性表的基本操作在顺序表中的实现
1、InitList(&L) // 结构初始化

Status InitList_Sq( SqList& L, int maxsize ) {
  // 构造一个最大容量为 maxsize 的顺序表 
  L.elem = new ElemType[maxsize];// 为顺序表分配大小为 maxsize 的数组空间
  if (!L.elem) exit(OVERFLOW);//存储分配失败
  L.length = 0;//空表长度为0
  L.listsize = maxsize;//初始存储量
  return OK;
}

2、LocateElem(L, e, compare()) // 查找
2、ListInsert(&L, i, e) // 插入元素
(1)查找的基本操作是:
将顺序表中的 元素逐个和给定值e相比较。
(2)一般情况下,在第i(1<=i<=n)个元素之前插入一个元素时,需要将第n至第i(共n-i+1)个元素向后移动一个位置。
(3)代码:

Status ListInsert_Sq(SqList &L, int i, ElemType e) {
  // 在顺序表L的第 i 个元素之前插入新的元素e,
 // i 的合法范围为  1≤i≤L.length+1
 if (i < 1 || i > L.length+1) return ERROR; // 插入位置不合法
 if (L.length >= L.listsize) { 
                          // 当前存储空间已满,增加分配
    newbase = (ElemType *)realloc(L.elem,                                                                 
         (L.listsize+LISTINCREMENT)*sizeof (ElemType));
    if (!newbase) exit(OVERFLOW);  
                           // 存储分配失败
    L.elem = newbase;                // 新基址
    L.listsize += LISTINCREMENT; // 增加存储容量
}
 **q = &(L.elem[i-1]);**        *// q 指示插入位置*
for (p = &(L.elem[L.length-1]); p >= q;  --p)  
     *(p+1) = *p;       *// 插入位置及之后的元素右移*
*q = e;  // **插入e**
++L.length;   // 表长增1
return OK;

(4)
若假定在线性表中任何一个位置上进行插入的概率都是相等的,则移动元素的期望值为 n/2

3、ListDelete(&L, i) // 删除元素
(1)一般情况下,删除第i(1<=i<=n)个元素时,需要将从第(i+1)至第n个元素(共n-i个)依次向前移动一个位置。
(2)代码:

Status ListDelete_Sq(SqList &L, int i, ElemType &e) {
if ((i < 1) || (i > L.length))  return ERROR; // 删除位置不合法
p = &(L.elem[i-1]);      // p 为被删除元素的位置
e = *p;                             // 被删除元素的值赋给 
q = L.elem+L.length-1;     // 表尾元素的位置
for (++p; p <= q; ++p)  *(p-1) = *p;// 被删除元素之后的元素左移
--L.length;       // 表长减1
return OK;
}

(3)若假定在线性表中任何一个位置上进行删除的概率都是相等的,则移动元素的期望值为:(n-1)/2
4、LocateElem(L, e, compare()) // 查找
(三)、总结
1、特点:以数据元素物理位置的相邻表示逻辑关系的相邻。
2、优点:随机存取
3、缺点:插入删除操作需移动较多数据元素。
4、若以线性表表示集合的各种运算,应先对表中的元素进行排序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pig2687

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值