数据结构之线性表
来源:互联网 发布:诸暨市行知小学介绍 编辑:程序博客网 时间:2024/06/06 08:28
一、线性表的概念和定义
1、线性表的逻辑结构特点
线性表是一种最简单的线性结构,是一个数据元素的有序(次序)集。
集合中必存在唯一的一个“第一元素”;
集合中必存在唯一的一个“最后元素”;
除最后元素之外,每个元素均有唯一的后继;
除第一元素之外,每个元素均有唯一的前驱;
2、线性表的基本术语
线性表可描述为n(n≥0)个具有相同特性的数据元素组成的有限序列。
常表示为:L={a1 ,…, ai-1, ai, ai+1, …, an};ai必须具有相同特性,即属于同一数据对象。
ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素;
数据元素ai在线性表中有确定的位置i,i称为位序;
线性表中数据元素的个数n称为线性表的长度,n=0时,线性表称为空表。
3、ADT定义
ADT List{
数据对象:
D={ai | ai∈ElemSet,i=1,2,...,n,n>=0} {称n为线性表的表长;称n=0时的线性表为空表。}
数据关系:
R1={<ai-1,ai>|ai-1,ai∈D,i=2,...,n } {设线性表为(a1,a2,...,ai,...,an), 称i为ai在线性表中的位序。}
}
基本操作:
结构初始化操作
结构销毁操作
引用型操作
加工型操作
}ADT List
GetElem(L,i,&e)
初始条件:
线性表L已存在,且1<=i<=LengthList(L).
操作结果:
用e返回L中第i个元素的值。
LocateElem(L,e,compare())
初始条件:
线性表L已存在,e为给定值,compare()是元素判定函数。
操作结果:
返回L中第一个与e满足关系compare()的元素的位序。若这样的元素不存在,则返回值为0.
ListTraverse(L,visit())
初始条件:
线性表L已存在,visit()为某个访问函数
操作结果:
依次对L的每个元素调用函数visit().一旦visit()失败,则操作失败。
PutElem(&L,i,&e)
初始条件:
线性表L已存在,且1<=i<=LengthList(L).
操作结果:
L中第i个元素赋值同e的值.
ListInsert(&L,i,e)
初始条件:
线性表L已存在,且1<=i<=LengthList(L)+1
操作结果:
在L的第i个元素之前插入新的元素e,L的长度增1.
ListDelete(&L,i,&e)
初始条件:
线性表L已存在且非空,1<=i<=LengthList(L).
操作结果:
删除L的第i个元素,并用e返回其值,L的长度减1.
二、线性表的顺序存储实现——顺序表
1.顺序存储(映像)方式
以x的存储位置和y的存储位置之间某种关系表示逻辑关系<x,y>.最简单的一种顺序映像方法是:令y的存储位置和x的存储位置相邻。
2.顺序表的C语言描述
#define List_INIT_SIZE 100 //线性表存储空间的初始分配容量
typedef struct
{
ElemType *elem; //存放线性表的数组空间基地址
int length; //当前长度(实际元素个数)
int listsize; //当前分配的容量
}SqlList;//称 顺序表
顺序表的基本形态
定义:sqList L;
空表
L.length==0 可插入不可删除
表满
L.length>=L.listsize 可删除不可插入(空间再分配)
表不空不满
0<L.lenth<L.listsize 可删除可插入
3、线性表的基本操作在顺序表中的实现
初始化:
Status InitList_Sq(SqList&L)
{
L.elem=(ElemType*)malloc(List_INIT_SIZE*sizeof(ElemType));
if(!L.elem) exit(OVERFLOW);
L.length=0;
L.listsize=List_INIT_SIZE;
return OK;
}//InitList_Sq
int Locate(SqList L,ElemType e)
{ //在顺序表L中查询第一个等于e的数据元素,若存在,则返回它的位序,否则返回0
i=1; //i的初值为第1元素的位序
for(i<=L.length;i++)
if(L.elem[i-1]==e)
return i;
return 0;
}//Locate
Status search_i(SqList L,int i,ElemType &e)
{//在顺序表L中查找第i个元素,若存在用e返回其值并返回OK,否则返回ERROR
if(i>0&&i<=L.length)
{
e=L.elem[i-1];
return OK;
}
else
return ERROR;
}
线性表的插入操作(ListInsert(&L,i,e))的实现:
分析:
插入元素时,线性表的逻辑结构发生了什么变化?
(a1,...,ai-1,ai,...,an)改变为(a1,...,ai-1,e,ai,...,an)
需考虑的问题(步骤)
1.当前表是否已满?
2.输入(插入位置)是否有效?
3.插入元素
Status ListInsert(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;//表容量更新
}
for(j=L.length;j>=i;j--)
L.elem[j]=L.elem[j-1];//插入位置及之后的元素右移
L.elem[i-1]=e;//插入e
++L.length;//表长+1
return OK;
}//ListInsert_Sq
线性表操作
ListDelete(&L,i,&e)的实现:
分析:
删除元素时,线性表的逻辑结构发生了什么变化?
(a1,a2,...,ai,ai+1,...,an)改变为(a1,a2,...,ai-1,ai+1,...an)
<ai-1,ai>,<ai,ai+1>——><ai-1,ai+1>
存储空间(顺序表)的变化:表的长度减少
Status ListDelete_Sq(SqList &L,int i,ElemType &e)
{//在顺序表L中删除第i个元素,以引用参数e返回其值,若删除成功返回ok;否则返回ERROR
if(i<1||i>L.length)
return ERROR;//i的值不合法
e=L.elem[i-1];
for(j=i;j<L.length;j++)
L.elem[j-1]=L.elem[j];//元素前移
--L.length;
return OK;
}//ListDelete_Sq
顺序表操作的效率分析
时间效率分析:
算法时间主要耗费在移动元素的操作上,而移动元素的个数取决于插入或删除元素的位置。
以插入为例分析
若插入在尾元素之后,则根本无需移动(特别快);
若插入在首元素之前,则表中元素全部要后移(特别慢);
Status Del_k(SqList&L,int i,int k)
{//在顺序表L中删除自第i个开始的k个元素,操作成功返回ok,否则返回error;
if(i>L.length||k>L.length-i+1)
return ERROR;
for(j=i+k-1;j<=L.length-1;j++)
L.elem[j-k]=L.elem[j];//元素前移完成删除
L.Length-=k;//顺序表长度减k
return OK;
}
小结——顺序表的特点:
优点:可以随机存取表中任一元素,方便快捷;
缺点:在插入或删除某一元素时,需要移动大量元素;需要预先确定数据元素的最大个数。
解决问题的思路:改用另一种线性存储方式:链式存储结构。
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- 数据结构之线性表
- git 使用笔记
- 行存储vs列存储
- java.lang.IllegalArgumentException: FacesContext must not be null 错误分析及解决
- OpenGL基础图形编程(八)变换
- stm32简说步进电机(有代码)!!!
- 数据结构之线性表
- bash和dash的区别
- 谷歌地图API基础
- 配置JDK环境变量
- 【1-0】mysql安装
- 数据库设计三大范式
- Android 调用另一个应用(app)中的Activity
- Rational Software Architect 的介绍和基础教程
- setsockopt和getsockopt函数解析