本节书摘来自华章出版社《数据结构与算法 C语言版》一 书中的第2章,第2.2节,作者:徐凤生,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.2线性表的顺序表示与实现

2.2.1线性表的顺序表示

线性表的顺序存储是指在内存中用一组地址连续的存储单元依次存储线性表的数据元素,用这种存储方式存储的线性表称为顺序表。顺序表中数据元素之间的逻辑关系通过其“存储位置相邻”来表示,如图21所示。

如果顺序表的数据元素是按照递增或递减顺序存放的,则称其为有序顺序表。
假设线性表的每个数据元素需占用l个存储单元,其第一个元素的存储地址,即数组的基地址记为LOC(a1),则线性表中第i个数据元素的存储地址LOC(ai)为
LOC(ai)=LOC(a1)+(i-1)*l
线性表中第i+1个数据元素的存储地址和第i个数据元素的存储地址之间具有以下关系:
LOC(ai+1)=LOC(ai)+l
由此可见,只要确定了线性表中第一个元素的存储位置,其他元素的存储位置就可以确定了,因此线性表的顺序存储结构是一种随机存取的存储结构。
由于高级程序设计语言中的数组具有随机存取的特性,因此,通常用数组来描述数据结构中的顺序存储结构。在此,由于线性表的长度可变,且所需最大存储空间随问题的不同而不同,因此在C语言中可采用动态分配的一维数组,描述如下:

//------------线性表的动态分配顺序存储结构-------------------
#define List_Size 100//线性表存储空间的初始分配量
#define ListIncrement 10//线性表存储空间的分配增量
typedef struct{
ElemType *elem;//存放线性表的数组基地址
int length;//线性表的当前长度
int listsize;//线性表当前分配的存储容量
}SqList;

2.2.2线性表的顺序实现

下面讨论在顺序存储结构下,线性表的基本操作是如何实现的。
1.顺序表的初始化
顺序表的初始化即构造一个空的线性表。设置length域的值为0表示线性表中没有元素,即为空表。算法描述如下:

void InitSqList(SqList &L){
L.elem=new ElemType[List_Size];
if(!L.elem)exit(OVERFLOW);
L.length=0;
L.listsize=List_Size;
}

2.建立顺序表
方法是依次将n个数据元素存入顺序表中。算法描述如下:

void CreateSqList(SqList &L,int n){//创建n个元素的顺序表
int i;
for(i=0;i<n;i++){
scanf("%d",&L.elem[i]);
L.length++;
}
}

3.销毁顺序表
该运算的结果是释放顺序表L占用的内存空间。算法描述如下:

void DeatroySqList(SqList &L){//销毁顺序表
delete L.elem;
}

4.插入操作
设线性表L=(a1,a2,…,ai-1,ai,ai+1,…,an),在第i个位置插入x是指在第i-1个数据元素和第i个数据元素之间插入一个新的数据元素x,即L变为(a1,a2,…,ai-1,x,ai,ai+1,…,an)。
数据元素x的插入使得ai-1和ai的逻辑关系发生了变化,并且L的长度由n变为n+1。显然,插入位置i满足1≤i≤n+1。如果i=n+1,则只需将x插入到an之后即可;如果1≤i≤n,则需将an~ai依次向后移动一个位置,然后将x插入到空出的第i个位置。算法描述如下:

int SqListInsert(SqList &L,int i,ElemType x){
int j;
ElemType *p;
if(i<1||i>L.length+1)return ERROR;//插入位置不合法
if(L.length>=L.listsize){//当前存储空间已满,增加存储空间
p=(ElemType *)realloc(L.elem,(L.listsize+ListIncrement)*sizeof(ElemType));
if(!p)exit(OVERFLOW);
L.elem=p;
L.listsize=L.listsize+ListIncrement;
}
for(j=L.length-1;j>=i-1;j--)L.elem[j+1]=L.elem[j];//插入位置之后的元素依次后移
L.elem[i-1]=x;//插入元素
++L.length;//表长增1
return OK;
}

下面对插入算法的时间复杂度进行分析。在顺序表中的某个位置插入一个数据元素,其时间主要消耗在移动元素上,而移动元素的个数取决于插入的位置和线性表的长度。
假设pi是在第i个位置插入一个元素的概率,则在长度为n的线性表中插入一个元素时所需移动元素的次数的期望值为
Eis=∑n+1i=1pi(n-i+1)
不失一般性,我们假设在线性表中的任何位置插入元素是等概率的,即pi=1n+1,则
Eis=∑n+1i=1pi(n-i+1)=∑n+1i=11n+1(n-i+1)=n2

所以,在顺序表中的插入操作约需移动一半的数据元素,其时间复杂度为O(n)。
5.删除操作
设线性表L=(a1,a2,…,ai-1,ai,ai+1,…,an),删除第i个元素ai,则L变为(a1,a2,…,ai-1,ai+1,…,an)。删除ai使得ai-1、ai和ai+1的逻辑关系发生了变化,并且L的长度由n变为n-1。显然,删除的位置i满足1≤i≤n。如果i=n,则只需删除an即可;如果1≤i≤n-1,则需将ai+1~an依次向前移动一个位置。算法描述如下:

int SqListDelete(SqList &L,int i){
int j;
if(i<1||i>L.length)return ERROR;//删除位置不合法
for(j=i-1;j<L.length-1;j++)L.elem[j]=L.elem[j+1];//删除位置之后的元素依次前移
--L.length;//表长减1
return OK;
}

下面对删除算法的时间复杂度进行分析。删除算法的主要操作仍是移动元素,而移动元素的个数取决于删除的位置和线性表的长度。
假设qi是在第i个位置删除一个元素的概率,则在长度为n的线性表中删除一个元素时所需移动元素的次数的期望值为
Edl=∑ni=1qi(n-i)
我们假设在线性表中的任何位置删除元素是等概率的,即pi=1n,则
Edl=∑ni=1pi(n-i)=∑n+1i=11n(n-i)=n-12

所以,在顺序表中的删除操作约需移动一半的数据元素,其时间复杂度为O(n)。
6.按值查找
线性表中按值查找是指在线性表中查找与给定值x相等的数据元素。其方法是:从第一个元素开始依次与x进行比较,直到找到一个与x相等的数据元素,并返回它在顺序表中的位序;若查遍顺序表都没有找到与x相等的数据元素,则返回ERROR。算法描述如下:

int LocateElem(SqList L,ElemType x){
int i=1;
while(i<=L.length&&L.elem[i-1]!=x)i++;
if(i<=L.length)return i;
else return ERROR;
}

查找算法的主要操作是比较元素。在查找成功的情况下,最好情况是要找的是第一个元素,比较次数是1;最坏的情况下是要找的是第n个元素,比较次数是n。如果查找第i个元素的概率是pi,找到第i个元素所需的数据比较次数为ci,则查找成功的平均期望值为∑ni=1pici。在等概率的情况下,平均期望值为∑ni=11ni=(1+n)/2。所以按值查找算法的时间复杂度为O(n)。

7.依次输出线性表中的所有元素

void DispSqList(SqList L){//输出顺序表
int i;
for(i=0;i<L.length;i++)printf("%d",L.elem[i]);
printf("\\\\n");
}

2.2.3顺序表的应用举例

例1将顺序表La=(a1,a2,…,ai-1,ai,ai+1,…,an)逆置。
解要想将La逆置,只需将第一个元素和最后一个元素交换,第二个元素和倒数第二个元素交换,以此类推,直到没有元素交换为止。算法描述如下:

void Contrary_Sq(SqList &La){//将顺序表逆置
int temp;
for(i=0;i<La.length/2;i++){
temp=La.elem[i];
La.elem[i]=La.elem[La.length-1-i];
La.elem[La.length-1-i]=temp;
}
}

例2设顺序表La中的数据元素递增有序。试编写算法,将x插入到顺序表的适当位置上,以保持该表的有序性。
解从顺序表La中的最后一个元素开始与x进行比较,若该元素大于x,则将该元素后移一个位置,否则将x插入到该元素的下一个位置。算法描述如下:

int Insert_OrderSq(SqList &La,ElemType x){
int i;
ElemType *p;
if(La.length>=La.listsize){//当前存储空间已满,增加分配
p=(ElemType*)realloc(La.elem,(La.listsize+ListIncrement)*sizeof(ElemType));
if(!p)exit(OVERFLOW);
La.elem=p;
La.listsize=La.listsize+ListIncrement;
}
for(i=La.length-1;x<La.elem[i]&&i>=0;i--)La.elem[i+1]=La.elem[i];
La.elem[i+1]=x;//插入元素x
++La.length;
return OK;
}

例3
有两个顺序表La和Lb,其元素均按从小到大升序排列。编写一个算法将它们合并成一个顺序表Lc,要求Lc的元素也是从小到大升序排列。
解1)初始化Lc为空表;2)分别从La和Lb中取得当前元素Laelem[i]和Lbelem[j];3)若Laelem[i]≤Lbelem[j],则将Laelem[i]插入到Lc中,并取La中的下一个元素;否则将Lbelem[j]插入到Lc中,并取Lb中的下一个元素;4)重复步骤3直至La或Lb中元素被取完为止;5)将La表或Lb表中剩余元素插入到Lc表中。算法描述如下:

void mergelist_Sq(SqList La,SqList Lb,SqList &Lc){//两个有序表的归并
int i,j,k;
InitSqList(Lc);
i=0;j=0;k=0;
while(i<Lalength&&j<Lblength){
if(Laelem[i]<=Lbelem[j]) Lc.elem[k++]=La.elem[i++];
else Lc.elem[k++]=Lb.elem[j++];
}
while(i<La.length)Lc.elem[k++]=La.elem[i++];//将La中剩余元素插入到Lc中
while(j<Lb.length)Lc.elem[k++]=Lb.elem[j++];//将Lb中剩余元素插入到Lc中
Lc.length=La.length+Lb.length;
}

由于上述算法的基本操作是元素赋值,所以算法的时间复杂度为O(La.length+Lb.length)。

《数据结构与算法 C语言版》—— 2.2线性表的顺序表示与实现相关推荐

  1. 《数据结构与算法 C语言版》—— 3.8习题

    本节书摘来自华章出版社<数据结构与算法 C语言版>一 书中的第3章,第3.8节,作者:徐凤生,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 3.8习题 1名 ...

  2. 《数据结构与算法 C语言版》—— 2.5上机实验

    本节书摘来自华章出版社<数据结构与算法 C语言版>一 书中的第2章,第2.5节,作者:徐凤生,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 2.5上机实验 实 ...

  3. 《数据结构与算法 C语言版》—— 2.7习题

    本节书摘来自华章出版社<数据结构与算法 C语言版>一 书中的第2章,第2.7节,作者:徐凤生,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 2.7习题 1描 ...

  4. 【数据结构与算法——C语言版】1. 数据结构与算法简介

    概念 数据结构:"一组数据的存储结构" 算法:"操作数据的一组方法" 数据结构是为算法服务的,算法是要作用再特定的数据结构上的. 简言之,在编程实践中,我们可能 ...

  5. 数据结构与算法C语言版—绪论

    1.基本概念和术语 1.数据(data):所有能输入到计算机中去的描述客观事物的符号 数值性数据 非数值性数据(多媒体信息处理) 2.数据元素(data element):数据的基本单位,也称结点(n ...

  6. c语言数据结构线性表LA和LB,数据结构(C语言版)设有线性表LA(3,5,8,110)和LB(2,6,8,9,11,15,20)求新集合?...

    数据结构(C语言版)设有线性表LA(3,5,8,110)和LB(2,6,8,9,11,15,20)求新集合? 数据结构(C语言版)设有线性表LA(3,5,8,110)和LB(2,6,8,9,11,15 ...

  7. 《数据结构》c语言版学习笔记——线性表的顺序存储结构

    线性表的顺序存储结构 第一章 线性表的顺序存储结构 文章目录 线性表的顺序存储结构 前言 一.顺序存储结构的建立 1.条件 2.代码 二.顺序存储结构的获得元素 1.条件 2.代码 三.顺序存储结构的 ...

  8. 数据结构(C语言版)之线性表

    前言 这学期学校开设了数据结构与算法,为帮助更多小伙伴和巩固学习,我开始整理这门课的学习内容,希望能给同样在学习这门课的小伙伴们提供一些浅薄的思路. 正文部分 目录 前言 正文部分 什么是线性表 整体 ...

  9. 数据结构和算法详解(二)——线性表(数组、链表、栈、队列)

    一.数组 线性表:   线性表就是数据排成像一条线一样的结构.每个现行表上的数据最多只有前和后两个方向.常见的线性表结构:数组,链表.队列.栈等. 什么是数组: 数组(Array)是一种线性表数据结构 ...

  10. c语言数据结构算法设计题,数据结构题集(C语言版)算法设计题答案[].doc

    数据结构题集(C语言版)算法设计题答案[].doc 第一章 绪论 1.16 void print_descending(int x,int y,int z)// 按从大到小顺序输出三个数 { scan ...

最新文章

  1. 微调torchvision 0.3的目标检测模型
  2. HTML5 Canvas 学习日志(三)
  3. MySQL的介绍以及使用
  4. 文本转声音,TTS语音实现
  5. mysql 重启_windows下重启mysql的方法
  6. python有哪些软件包用来考察变量之间的相关性_Python语言基础考察点:python语言基础常见考题(一)...
  7. linux 深度 root,深度刷机让毫秒级一键ROOT成为现实
  8. Spring容器启动后注入service到Servlet并自动执行
  9. 深入理解Nginx及使用Nginx实现负载均衡
  10. SQL 2016——新功能
  11. 软考高项的工作前景:
  12. Vue项目 在chrome页面崩溃:喔唷 崩溃了(总结)
  13. jquery实现返回顶部功能
  14. openstack-Agile Controller-DCN插件安装
  15. 中国染料医用激光器行业市场供需与战略研究报告
  16. 2016届阿里实习生java研发岗一面二面三面四面经验分享
  17. pcl点云特征提取 法线估计 PFH FPFH NARF 惯量偏心矩 RoPs特征 视点特征直方图VFH GASD特征
  18. ice的意思_ice是什么意思_ice怎么读_ice翻译_用法_发音_词组_同反义词_冰-新东方在线英语词典...
  19. 怎样在线压缩JPEG图片大小?
  20. 求求你们,这次不要放过东北

热门文章

  1. 如何使用Vegas Pro制作遮罩转场效果?
  2. The JRE you are running Eclipse with appears to not be a JDK .Spring Boot Live hovers will not work
  3. 如何使用EasyRecovery进行深度扫描和继续扫描
  4. Django入门4--admin
  5. WebForm读取指定的config文件的内容
  6. 第二十九篇、UICollectionView瀑布流
  7. I/O多路复用之select
  8. Codeforces Round #334 (Div. 2) A. Uncowed Forces 水题
  9. 常用的字符串分割方法
  10. poj 2263 Heavy Cargo floyd基础,就是输入的时候处理字符串纠结一点!!!!