考纲内容
(一)线性表的基本概念
(二)线性表的实现{顺序存储;链式存储}
(三)线性表的应用
思维导图
tips:单链表、双链表、循环链表都是通过指针实现。
提示:该章节是基础,根据思维导图来复盘知识点基本上就算是掌握了这一章节。
线性表
线性表是具有相同数据类型的n(n>0)个数据元素的有限序列,其中n为表长,当n=0时,线性表为空表。
Tips:除了第一个元素之外,每个元素有且仅有一个前驱。除了最后一个元素之外,每个元素有且只有一个后继。线性表是一种逻辑结构,表示元素一对一的相邻关系,顺序表和链表是指存储结构。
顺序表(可以理解为数组)
线性表的顺序存储是顺序表。它是由一组连续的存储单元一次存储在线性表中的数据元素,即逻辑顺序与物理顺序都是相同的。
Tips:线性表中元素的位序是从1开始的,数组下标是从0开始。
基本操作
定义其结构类型
#define MaxSize 50
typedef struct{
ElemType data[MaxSize]; //顺序表元素
int length; //顺序表长度
}SqList; //顺序表类型定义
一维数组是可以静态分配,也可以动态分配,两者分配方式均是属于顺序存储结构,物理结构无变化,依旧是随机存储方式。在静态分配中有可能出现空间不足导致数据溢出,进而使程序崩溃;动态分配会根据动态存储分配语句进行开辟一块更大的空间用于存储数据,并以此替换原有的数据空间。
下面演示动态分配语句:
#define InitSize 100
typedef struct{
ElemType *data; //动态分配数组指针
int MaxSize,length; //数组最大容量和当前个数
}SeqList; //动态分配数组顺序表的类型定义
C语言版本的初始动态分配语句
L.data = (ElemType)malloc(sizeof(ElemType)*InitSize);
C++的初始动态分配语句
L.data = new ElemType[InitSize];
顺序表最主要特点为随机访问,即通过首地址和元素序号可在O(1)内找到指定元素。
顺序表的插入操作
插入操作,即在顺序表L中第i个位置插入元素e。
其代码思想:判断第i个位置是否合法,若i输入不合法,则返回false,表示插入失败,否则,将第i个元素及其后的元素往后移动一位,留出一个空间插入新元素e
bool ListInsert(SqList &L,int i,ElemType e ){
if(i<1||i>Length+1) //判断i是否有效
return false;
if(L.Length>MaxSIze) //当前存储空间已满,无法插入
return false;
for(int j=L.Length;j>=i;j--) //将第i个元素及之后的元素后移
L.data[j]=L.data[j-1];
L.data[i-1]=e; //在位置i处放入e,这里注意,数组下标和顺序表的位序的关系
L.Length++; //线性表长度加1
return true;
}
最好情况:表尾插入,时间复杂度为O(1)
最坏情况:表头插入,时间复杂度为O(n)
平均情况:假设每一次的概率为Pi,对长度为n的线性表插入节点,移动平均次数为(1/n+1)* n*(n+1)/2 =n/2
线性表插入算法的平均时间复杂度为O(n)
顺序表的删除操作
删除顺序表L第i个元素,用引用变量e返回。
其代码思想:判断第i个位置是否合法,若i输入不合法,则返回false,表示删除失败,否则,将被删元素赋给引用变量e,将第i+1个元素及其后的元素往前移动一位
bool ListDelete(SqList &L,int i,ElemType &e){
if(i<1||i>Length+1) //判断i是否有效
return false;
e=L.data[i-1]; //将被删除的元素e赋值给e
for(int j=i;j<L.Length;j++) //将第i个位置的元素前移
L.data[j-1]=L.data[j];
L.Length--; //线性表长度减1
return true;
}
最好情况:表尾删除,无需移动元素,时间复杂度为O(1)
最坏情况:表头删除,移动所有元素,时间复杂度为O(n)
平均情况:假设每一次的概率为Pi,对长度为n的线性表删除节点,移动平均次数为(1/n)* n*(n-1)/2 =n-1/2
线性表删除算法的平均时间复杂度为O(n)
顺序表的按值查找操作
在顺序表L中查找第一个元素值等于e的元素,并返回位序。
int LocateElem(SqList L,ElemType e){
int i;
for(i=0;i<L.Length;i++)
if(L.data[i]==e)
return i+1; //元素值等于e,返回位序为i+1
return 0; //退出循环,查找失败
}
最好情况:查找元素在表头,仅需查找一次
最坏情况:查找元素在表尾,需要比较n次,时间复杂度为O(n)
平均情况:假设每一次的概率为Pi,对长度为n的线性表比较节点,比较平均次数为(1/n)* n*(n+1)/2 =n+1/2
线性表删除算法的平均时间复杂度为O(n)