一、线性表的顺序存储实现
1、描述顺序表需要几个属性
- 存储空间起始的位置:Data
- 存储的容量:MaxSize
- 当前长度:last(=n-1)
2、顺序表的数据类型描述
typedef struct{
DataType data[MaxSize];
int last;
}SeqList;
说明
①
若 把顺序表定义为 SeqList L;
则 表长表示为 L.last+1
顺序表各元素表示为 L.data[0]~L.data[L.last]
若 把顺序表定义为 SeqList *L;
则 表长表示为 L->last+1
顺序表各元素表示为 L->data[0]~L->data[L->last]
②
顺序表定义为 SeqList*L;
表空条件:L->last= -1
表满条件:L->last= MaxSize-1
二、顺序表主要操作的实现
1、初始化:构造空的顺序表,为它分配存储空间
顺序表的初始化算法
SeqList *Init_SeqList( ){
SeqList *L;
L= new SeqList;
L->last=-1;
return L;
}
2、插入运算
2.1后移操作如何实现?新元素如何置入?
for (j=L->last; j>=i-1; j--)
L->data[j+1]= L->data[j];
L->data[i-1]=x;
2.2什么时候不能插入
表满:L->last = =MaxSize-1
合理的插入位置:1≤i≤表长+1(i:元素序号)
不合理的插入位置:i<1 或i>表长+1
算法:
int Insert_SeqList (SeqList *L,int i,DataType x )
{
int j;
if (L->Last==MaxSize-1){
printf(“overflow error! \n”); /*上溢返回0*/
return 0;
}
else if ((i<1)||(i>L->Last+2)){
printf (“wrong position! \n”);
return 0 ;
}
else {
for (j=L->last; j>=i-1; j--)
L->data[j+1]= L->data[j];
L->data[i-1]=x;L->data[i-1]=x;
}
2.3插入算法的时间性能分析:
- 在第i个位置上插入x,需移动n-i+1个元素
i的取值范围为:1≤i≤ n+1,即有n+1个位置可以插入 - 顺序表上插入操作需移动表中一半的元素,时间复杂度为O(n)。
3、删除运算
算法:
intDelete_SeqList( SeqList*L,inti){
int j;
if ( i<1 || i> L->last+1 )
{ /*删除位置无效,返回0*/
printf(“wrong position!\n”);
return 0;
}
for ( j=i; j<=L->last; j++) /*前移*/
L->data[j-1]= L->data[j];
L->last --;return 1;
}
3.1删除算法时间性能分析:
- 删除第i个位置上的元素,需移动n-i个元素
i的取值范围为:1≤i≤ n,即有n个位置可以删除 - 顺序表上删除操作需移动大约表中一半的元素,时间复杂度为O(n)。
4、查找运算
算法
intLocation_SeqList( SeqList*L,DataTypex){
inti;
i=0;
while (i<=L->last && L->data[i]!=x)
i++;
if (i>L->last)
return -1;
else
return i;
}
4.1查找算法时间性能:
•主要运算:比较i
•比较次数与x在表中位置有关
•最好:a1=x 比较1次
•最坏:an=x 比较n次
•平均:比较(n+1)/2次,时间复杂度为O(n)
作业
题:有一组按顺序排列好的数,现在让你插入一个数,且保持原排列顺序不变。
普通人的想法:
从第一个开始查询,同时比较大小,若插入的数大,下一个,若插入的数小,则插入。
此方法需操作两次数组,容易想,但是不聪明
好一些的方法:
二分法,因为是排列好的,中间开始,比较,在中间,很快即找到位置,但是还是操作两次,还是不够聪明
聪明的操作:
从数组的最后开始比较数,若插入的数小则前移,同时将数组的最后一个数后移,这样找到插入位置,只对数组做了一次操作。聪明!