线性表的顺序存储及操作

存储的表示

#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)

顺序存储结构的优点和缺点

优点:
① 无需为表示结点间的逻辑关系而增加额外的存储空间;
② 方便地随机存取表中元素。
缺点:
① 插入或删除不便:
除表尾位置外,插入或删除操作都须移动大量结点,效率较低;
② 要求连续存储空间:
存储分配只能预先进行静态分配。表长变化较大时,难以确定合适的存储规模。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值