1.什么是线性表
2.线性表的抽象数据类型描述
3.线性表的顺序存储实现
顺序表的定义
/*
顺序表的定义
*/
typedef struct LNode * List; //将struct LNode *类型重命名为List
struct LNode //用数组定义struct LNode类型,即线性表
{
//用数组定义:数组长度;头或尾的地址
ElementType Data[MAXSIZE]; //定义数组,数组中的元素类型是ElementType,数组的长度是MAXSIZE,数组的名字是Data
//数组的下标从0到MAXSIZE-1
int Last; //定义数组最后一个元素的下标为Last
};
struct LNode L; //定义struct LNode类型的变量,变量名为L
List PtrL; //定义struct LNode *类型的变量,变量名为PtrL
//访问下标为i的元素:L.Data[i] 或者PtrL->Data[i]
//线性表的长度:L.Last + 1或PtrL->Last + 1 //因为是从0开始的,所以+1
顺序表的初始化
/*
初始化
*/
List MakeEmpty()
{
List PtrL; //定义一个struct LNode *变量,变量名为PtrL
PtrL = (List)malloc(sizeof(struct LNode)); //动态分配空间,并将空间的首地址赋给PtrL
PtrL->Last = -1; //Last为0表示它是线性表的第一个元素,没有元素,则将Last置为-1
return PtrL; //返回该线性表的指针
} //返回值是struct LNode *
查找
/*
查找
查找成功的平均比较次数是(n+1)/2(最好情况是被查找的值在表头->查找1次,最坏情况是,被查找的值在表尾->查找n次)
时间复杂度:O(n)
*/
int Find( ElementType X, List PtrL)
{
int i = 0;
while (i <= PtrL->Last && PtrL->Data[i] !=X) //i <= PtrL->Last表示从第一个找到最后一个元素,
//PtrL->Data[i] !=X表示比较第i个元素的值是不是X
i++; //当找到X的值或者遍历完所有元素时,跳出循环
if (i > Ptrl->Last) //遍历完所有元素的情况->没找到
return -1; //返回-1
else return i; //找到了,返回的是存储位置
}
插入
/*
插入:在线性表第i(i<=i<=n+1)个位置上插入一个值为X的新元素
对应的,即在数组的第i-1个位置插入
分析:
把线性表中第i-1及以后的所有元素都往后挪一个位置
步骤:先移动,再插入
注:从表尾开始移动,即先将an移到an+1,再把an-1移到an的位置,以此类推
时间复杂度:O(n)
平均移动次数:n/2 (最好情况是,插入到表尾->移动0次,最坏情况是,插入到表头,移动n次)
*/
void Inset(ElementType X, int i, List ptr)
{
int j;
if (PtrL->Last == MAXSIZE-1) //判断数组是否满了
{
printf("表满";)
return;
}
if (i <1 || i>PtrL->Last+2) //判断插入位置是否合法z,
//原来表长是Last+1,加入一个新元素成功后的表长是Last+2,当i = Last +2时表示插入到表尾了
{
printf("位置不合法"); //如果i比1小,或者比数组的表长还大,则不合法
return;
}
for (j = PtrL->Last; j >= i-1; j--) //将ai~an倒序向后移动
PtrL->Data[j+1] = PtrL->Data[j]; //最后一步是把线性表中第i个元素的值赋给第i+1个,腾出线性表中第i个的格子
//即要把数组第i-1项的值赋给第i项
PtrL->Data[i-1] = X; //在线性表第i个位置插入新元素,即为数组i-1项赋值
PtrL->Last++; //等价于 PtrL->Last = PtrL->Last + 1; 因为表长+1了,所以Last也要+1
// Last仍然指向线性表最后一个元素
}
/*
总结:
插入的实质是把要插入的元素的值赋给数组里面相应的位置
我要把这个新的值放到数组的某个位置,但是这个位置已经有值了,所以要把这个值往后挪,给新的值腾地方
数组的空间是给定的,只是赋值让线性表看起来是插入了一个新的元素
*/
删除
/*
删除:删除线性表的第i(1<=i<=n)个位置的元素
对应的,即删掉数组第i-1个元素
分析:把数组中第i个及以后的所有元素都往前移
注:从第i个位置开始,用第i个元素的值覆盖第i-1个元素的值,达到删除目的
时间复杂度:O(n)
平均移动次数:(n-1)/2(最好情况是,被删除的元素在表尾->移动0次,最坏情况是,被删除的元素在表头,即除了第一个元素,其他元素都被移动了->移动n-1次)
*/
void Delete ( int i, List PtrL)
{
int j;
if( i<1 || i>PtrL->Last+1) //检查i是否为空及删除位置是否合法,当i<1或者i>表长时都不合法
{
printf("不存在第%d个元素", i);
return;
}
for (j=i; j<=PtrL->Last; j++) //将ai~an顺序向前移动
PtrL->Data[j-1] = PtrL->Data[j]; //把线性表第i+1项的值赋给第i项,即在数组中,把第j项的值赋给第j-1项
PtrL->Last--; //删除后表长-1,所以Last-1,Last仍然指向最后一个元素
return;
}
/*
总结:
和插入类似,删除的实质就是用后面的值覆盖要删除的值
同样的,线性表的内存是给定的,删除一个元素,就把它的值用其他元素覆盖即可
*/