存储的表示
#define MAXSIZE 100
typedef struct
{
ElemType elem[MAXSIZE];
int last/*记录线性表中最后一个元素在数组elem[]的位置
(下标值),空表置为一 */
} SeqList;
PS:
1、结点类型定义中 Elemtype 是为了描述的统一而自定的,实际应用中可以根据自己具体的数据类型来定义(int, char, float 等)。
2、注意区分元素序号与数组下标的关系。
变量L两种定义和使用方法:
1、 SeqList L;
通过L.last
得到最后一个元素的下标,L.last+1
就是顺序表的长度;
2、 SeqList L1, *L; L=&L1;
通过L->elem[i-1]
来访问ai
,使用L->last+1
得到顺序表的长度。
基本运算
1、查找操作
① 按序号查找GetData(L,i)
:查找L中第i个元素;
② 按内容查找Locate(L,e)
:查找L中与给定e相等的元素。
算法描述:
int Locate(SeqList L,ElemType e)/*找到该元素,返回i+1;找不到则返回-1*/
{
i=0;
while((i<=L.last)&&(L.elem[i]!=e))/*一直找,直到找到e为止*/
i++;
if(i<=L.last)
return(i+1);
else
return(-1);
}
此算法时间复杂度为O(n)
。
2、插入操作
在表第i (1≤i≤n+1)
个位置,插入一个新元素e,表长+1(n+1)。
算法描述:
#define OK 1
#define ERROR 0
int InsList(SeqList *L, int i, ElemType e)/*i范围是1~L->last+2*/
{
int k;
if((i < 1) || (i > L->last+2)) /*判断插入位置是否合法*/
{ printf("插入位置i值不合法");
return(ERROR);
}
if(L->last >= MAXSIZE-1)
{ printf("表已满无法插入");
return(ERROR);
}
for(k = L->last; k >= i-1; k--) /*移动元素让位*/
L->elem[k+1] = L->elem[k];
L->elem[i-1] = e; /*插入元素e*/
L->last++; /*更新表长*/
return(OK);
}
PS:
1、在表尾(i=L->last+2
)插入元素时,可直接在表尾插入e;
2、注意i的取值范围,1=<i<=L->last+2
;
3、长度为n的表中插入一元素所需移动元素的平均次数是n/2
.
3、删除操作
将第i(1≤i≤n)
个元素删去,使长度为n的线性表变成长度为n-1的线性表。
算法描述:
int DelList(SeqList *L,int i,ElemType *e) /*用指针参数e取值后删除*/
{
int k;
if((i < 1) || (i > L->last+1))
{
printf(“删除位置不合法!”);
return(ERROR);
}
*e= L->elem[i-1]; /* 取元素到e指向的变量中*/
for(k = i; k <= L->last; k++) /*后面元素依次前移*/
L->elem[k-1] = L->elem[k];
L->last--;
return(OK);
}
PS:
1、当删除表尾(i=L->last+2
)时,不需要移动元素,仅将表长度减一即可;
2、注意i的取值范围,1=<i<=L->last+1
;
3、长度为n的表中删除一元素所需移动元素的平均次数是n-1/2
.
4、合并运算
将元素非递减有序排列顺序表LA和LB合并成元素非递减顺序表LC。
算法思想 :
① 设两个指针(下标)i、j分别指向表LA和LB中的元素;
② 若LA.elem[i] <= LB.elem[j]
,则将LA.elem[i]
插入到表LC中;
③ 否则将LB.elem[j]插入到表LC中,移动相应指针;
④ 循环直到LA或LB被扫描完毕,再将未扫描完的表中剩余元素复制到表LC中。
算法描述:
void mergeList(SeqList *LA, SeqList *LB, SeqList *LC)
{
int i,j,k;
i = 0; j = 0; k = 0;//A、B、C三表从头处理
while(i <= LA->last && j <= LB->last)//A、B表都未扫描完
if(LA->elem[i] <= LB->elem[j])
{
LC->elem[k] = LA->elem[i];
i++; k++;
}
else
{
LC->elem[k] = LB->elem[j];
j++; k++;
}
while(i <= LA->last) /*表LA未完,余下元素赋给表LC*/
{
LC->elem[k] = LA->elem[i];
i++; k++;
}
while(j <= LB->last) /*表LB未完,余下元素赋给表LC*/
{
LC->elem[k] = LB->elem[j];
j++; k++;
}
LC->last = LA->last + LB->last+1;//计算LC表长
}
PS:
LC的建立采用的是尾插法,插入时不需要移动元素,时间复杂度为O(LA->last+LB->last)
。
顺序存储结构的优点和缺点
优点:
① 无需为表示结点间的逻辑关系而增加额外的存储空间;
② 方便地随机存取表中元素。
缺点:
① 插入或删除不便:
除表尾位置外,插入或删除操作都须移动大量结点,效率较低;
② 要求连续存储空间:
存储分配只能预先进行静态分配。表长变化较大时,难以确定合适的存储规模。