数据结构——顺序表的基本操作
结构体
Tips:该节代码基于静态分配实现,静态分配与动态分配的代码基本一致
静态分配
#define MaxSize 10 //定义最大长度
typedef struct{
ElemType data[MaxSize]; //用静态的“数组”存放数据元素
int length; //顺序表的当前长度
}SqList; //顺序表的类型定义
动态分配
#define InitSize 10 //顺序表的初始长度
typedef struct{
ElemType *data; //指示动态分配数组的指针
int MaxSize; //顺序表的最大容量
int length; //顺序表的当前长度
} SeqList; //顺序表的类型定义
插入
ListInsert(&L,i,e):在表L中的第i个位置上插入指定元素e。
表L中第i个位置:L.data[i-1]——元素在数组中的位置
代码分析
特殊情况
1.插入位置i的范围:i>=1&&i<=L.length+1
2.存储空间的大小:L.length<MaxSize
思路
1.从后往前覆盖——j从L.length到i循环,保证从i到L.length每一个元素都会被选择
2.将L.data[j]该元素前一个元素赋值给该元素,保证在上一次赋值之后,下一次赋值时前一个元素的值不会丢失
3.在数组容量够时,保证L.data[L.length]该元素存在
图解
分析:在元素d处插入元素c,元素d、e、f向后移动,元素c放入到移动前d的位置
时间复杂度
重点:平均时间复杂度
1.概率p——总共有n+1种情况,每种情况可能性相等
2.总循环次数——n+1种情况,每种情况的循环次数相加总和
删除
ListDelete(&L,i,&e):删除表L中第i个位置的元素,并用e返回删除元素的值。
表中第i个位置:L.data[i-1]——元素在数组中的位置
代码分析
特殊情况
1.插入位置i的范围:i>=1&&i<=L.length
思路
1.先用e存储表L中第i个位置的元素,保证在删除元素后该元素的值不会丢失
2.从前往后覆盖——j从i到L.length-1循环,保证从i到L.length-1每一个元素都会被选择
3.将L.data[j]该元素的值赋给前一个元素,保证在上一次赋值之后,下一次赋值时后一个元素的值不会丢失
图解
分析:删除数组中的元素c,元素d、e、f向前覆盖,e返回删除元素的值
时间复杂度
重点:平均时间复杂度(与插入类似)
1.概率
2.总循环次数
查找
按位查找
GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值
ElemType GetElem(SeqList L, int i){
return L.data[i-1];
}
代码分析:和访问普通数组的方法一样
时间复杂度
O(1)——顺序表的各个数据元素在内存中连续存放,可以根据起始地址和数据元素大小立即找到第 i 个元素(随机存取特性)
按值查找
LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。
//在顺序表L中查找第一个元素值等于e的元素,并返回其位序
int LocateElem(SeqList L,ElemType e){
for(int i=0;i<L.length;i++)
if(L.data[i]==e)
return i+1; //数组下标为i的元素值等于e,返回其位序i+1
return 0; //退出循环,说明查找失败
}
代码分析:对整个顺序表进行逐一对比即可
时间复杂度
重点:平均时间复杂度(与前面类似)
1.概率
2.总循环次数