顺序表:用一组连续的存储单元(地址连续)依次存放线性表的各个数据元素。
即:在顺序表中逻辑结构上相邻的数据元素,其物理位置也是相邻的。
//线性表的动态分配顺序存储结构
#define List_INIT_SIZE 100;//线性表存储空间的初始分配量
#define LISTINCREMNT 10;//线性表存储空间的分配增量
typedef struct{
ElemType *elem;//分配空间基址
int Length;//当前长度
int Listsize;//当前分配的存储容量
}Sqlist;
内存分配:Sqlist L;
L.elem=(ElemType *)malloc(LIST_INIT_SIZE *sizeo(ElemType));
顺序表的几种操作:
-
插入算法
在第i(1<=i<=n+1)个元素之前插入一个新的数据元素x。使:长度为n的线性表变为长度为n+1的线性表。 -
算法思想
若i=n+1,则将x插入到表尾;
若表长度n<0或插入的位置不适当,则输出错误信息,并返回-1;
若1<=i<=n,则从表尾开始到i,依次向后移动一个位置(共需要移动n-i+1个数据元素)。最后将x存入v[i]中,表长n增1,插入成功,函数返回值为0。
Status Listlnsert_Sq(SqList &L,int i,ElemType e){
//在顺序线性表L中第i个位置之前插入新的元素e
//i的合法值为1<=i<=ListLenth_sq(L)+1
if(i<1||i>L.Lenth+1) return ERROR;//i值不合法
if (L.Lenth>=L.Listsize){//当前存储空间已满,增加分配
newbase=(ELemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase) exit(OVERLOW);//存储分配失败
L.elem=newbase;//新基址
L.listsize+=LISTINCREMENT;
}//增加存储容量
q=&(L.elem[i-1]);//q为插入的位置
for(p=&(L.elem[L.lenth-1];p>=q;--p)
*(p+1)=*p;//插入位置及后至的元素右移
*q=e;//插入e
++L.lenth;//表长增1
return OK;
}//ListInsert_sq
算法时间复杂度T(n)=O(n)
-
删除算法
将线性表的第i(1<=i<=n)个结点删除,使:长度为n的线性表变为长度为n-1的线性表。 -
删除的算法思想
若i=n,只需删除终端结点,不用移动结点;
若表长度n<=0或删除的位置不适当,则输出错误信息,并返回-1;
若1<=i<=n,则将表中结点ai+1,ai+2,…,an依次向前移动一个位置(共需移动n-i个数据元素)。最后将表长n减1,删除成功,函数返回值为0.
Status ListDelete_Sq(SqList &L,int i,ElemType e){
//在顺序线性表L中删除第i个元素,并用e返回其值
//i的合法值为1<=i<=ListLenth_sq(L)
if(i<1||i>L.Lenth) return ERROR;//i值不合法
p=&(L.elem[i-1]);//p为被删除元素的位置
e=*p;//被删除的元素的值赋值给e
q=L.elem+L.lenth-1;//表尾元素位置
for(p++;p<=q;++p)
*(p-1)=*p;//被删除之后的元素左移
--L.lenth;//表长减1
return OK;
}//ListDelete_sq
注释: q=L.elem+L.lenth-1;
L.elem是一个指针,指向表头元素,
L.lenth是该顺序表(可以理解为数组)的长度(可以理解为表的元素个数)
/*
typedef struct{
ElemType * elem; // 指向表头元素
int length;
} L ;
这个题目要是再严谨点,如果q是指向顺序表尾(最后一个元素)的话,那么L.elem 应该是指向第一个元素之前,也就是“额外”添加的一个头元素.
*/
算法时间复杂度T(n)=O(n)
-
合并顺序表
已知顺序表La和Lb的顺序按值非递减排列,归并La和Lb得到新的顺序表Lc,Lc的元素也按值非递减排列
基本操作是“复制”,设2个指针i和j,分别指向2个表当前处理的元素,当i不大于j时复制i所指元素到Lc中,否则复制j所指元素到Lc中