2.4 线性表的顺序表示和实现
2.4 线性表的顺序表示和实现
线性表的顺序表示又称为顺序存储结构或顺序映像
顺序存储定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中存储结构
逻辑上相邻的元素,物理上也是相邻的。
线性表顺序存储结构占用一片连续的存储空间。知道某个元素的存储位置就可以计算其他元素的存储位置。
优点:以物理位置相邻表示逻辑关系。任意元素均可随机存储。
线性表运用高级语言进行定义
#define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量
typedef struct{
ElemType elem[LIST_INIT_SIZE];
int length; // 当前线性表所存储数据元素长度
}SqList;
注意:逻辑位序与物理位序相差1
补充线性表的相关函数结果的状态码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
// Status 是函数类型,其值是函数结果状态代码
typedef int status;
typedef char ElemType;
线性表L的初始化
-
【算法描述】
Status InitList_Sq(SqList &L){ // 构造一个空的顺序表 L.elem=new ElemType[MAXSIZE]; // 为顺序表分配空间 if(!L.elem) exit(OVERFLOW); // 存储分配失败 L.length=0; // 空表长度为0 return OK; }
销毁线性表
void DestroyList(SqList &L){
if(L.elem)
delete L.elem;
}
清空线性表
-
【算法描述】
void ClearList(SqList &L){ L.length=0; // 将线性表的长度置为0 }
求线性表的长度
-
【算法描述】
int GetLength(SqList L){ return L.length; }
判断线性表是否为空
-
【算法描述】
int IsEmpty(SqList L){ if(L.length==0) return 1; else return 0; }
顺序表的取值(根据位置i获取相应数据元素的内容)
-
【算法描述】
int GetElem(SqList L,int i,ElemType &e){ if(i<1||i>L.length) return ERROR; // 判断i值是否合理,返回ERROR e=L.elem[i-1]; // 第i-1的单元存储着第i个数据 return OK; }
【算法分析】结果为O(1)
顺序表的查找
-
在线性表的L中查找与指定值e相同的数据元素的位置
-
【算法思想】从表的一端开始,逐个进行记录的关键字和给定值的比较。找到,返回该元素的位置序号,未找到,返回0;
-
【算法描述】
int LocateElem(SqList L,ElemType e){ // 在线性表L中查找值为e的数据元素,返回其序号(是第几个元素),这里只是返回首次查找到的结果 for(i=0;i<L.length;i++) if(L.elem[i]==e) return i+1; // 查找成功,返回序号 return 0; // 查找失败,返回0 }
-
【算法分析】
-
因为查找算法的基本操作为:将记录关键字同给定值进行比较
顺序表的插入
-
线性表的插入运算是指在表的第i个位置上,插入一个新结点e,使长度为n的线性表编程长度n+1的线性表
-
算法思想:
- 判断插入位置i是否合法(0~n)
- 判断顺序表的存储空间是否已满,若已满返回ERROR。
- 将第n至第i位的元素依次向后移动一个位置,空出第i个位置。
- 将要插入的新元素e放入第i个位置。
- 表长加1,插入成功返回OK。
-
【算法描述】
Status ListInsert_Sq(SqList &L,int i,ElemType e){ if(i<1||i>L.length+1) // i值不合法 return ERROR; if(L.length==MAXSIZE) // 当前存储空间已满 return ERROR; for(j=L.length-1;j>=i-1;j--) // 将后面依次向后移动1位,保证第i-1个位置进行空出 L.elem[j+1]=L.elemp[j]; L.elem[i-1]=e; // 将第i-1个位置赋值 L.length++; return OK; }
-
算法时间主要耗费在移动元素的操作上
- 若插入在尾结点之后,则根本无需移动其他节点。
- 若插入在首结点之前,则表中元素全部后移;
- 若要考虑在各种位置插入(共有n+1中可能)的平均移动次数,该如何计算?
共有n+1个位置,所以每个位置的可能为1/n+1,移动(n-i+1)
顺序表的删除
线性表的删除运算是指将表第i个个结点进行删除,使长度为n的线性表变成为长度为n-1的线性表。
-
【算法思想】
- 判断删除位置i是否合法(合法值为1<=i<=n)
- 将欲删除的元素保留在e中
- 将第i+1至第n位的元素依次向前移动一个位置。
- 表长减1,删除成功返回OK
-
【算法描述】
Status ListDelete_Sq(SqList &L,int i){ if(i<1||i>L.length) // 判断i值是否合法 return ERROR; for(j=i;j<=L.length;j++){ L.elem[j-1]=L.elem[j]; // 被删除元素之后的元素前移 } L.length--; // 表长减1 return OK; }
-
算法时间主要耗费在移动元素的操作上
- 若删除尾结点,则根本无需移动;
- 若删除首结点,则表中的n-1个元素全部前移(特别慢)
- 若要考虑在各种位置删除(共n种可能)的平均移动次数,该如何计算?
共有n个元素,所以每个元素1/n,需要移动元素为(n-i)个。两者相乘即可
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!