线性表及其操作

我是研究僧i 提交于 2020-01-30 02:30:29

1. 线性表的定义
线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列。其中n为表长,当n=0时,该表为空表。
逻辑结构:L = (a1,a2,…,ai,…,an)

2. 线性表的顺序表示
线性表的顺序存储又称顺序表。它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。
在这里插入图片描述
3. 顺序表上的基本操作的实现

(1)插入操作(前插)
在顺序表L的第i(1≤i≤L.length+1)个位置插入新的元素e。
代码:

# include <stdio.h>
# define MaxSize 50   // 定义线性表的最大长度 

typedef struct{
	int data[MaxSize]; // 顺序表的元素 
	int length=0;        // 顺序表的当前长度 
}SqList; 

// 函数声明
bool ListInsert(SqList &L,int i,int e); 
void PrintList(SqList L);

int main (void){
	SqList L;
	int i;
	for(i = 1; i <= 10; i++){
		if(!ListInsert(L,i,i)){  // 注意这里传的是L,不是&L 
			printf("插入异常");
			break;
		}														
	}
	
	PrintList(L);
	
	return 0;
}

// 在顺序表的第i个位置插入新元素e
bool ListInsert(SqList &L,int i,int e){
	if(i<1 || i>L.length +1)     // 判断位置合法性 
		return false; 
	if(L.length >= MaxSize)		// 判断长度合法性 
		return false;
		
	for(int j=L.length; j>=i;j--){ // 挪动后面的元素 
		L.data[j] = L.data[j-1];
	}
	L.data[i-1] = e;            // 放置新元素 
	L.length++;					// 长度增加 
	
	return true;   
} 

// 依次输出顺序表的所有元素
void PrintList(SqList L){
	for(int i = 0; i < L.length; i++){
		printf("--%d",L.data[i]);
	}
} 

最好情况:在表尾插入(即 i=n+1),元素不后移,时间复杂度O(1)
最坏情况:在表头插入(即 i=1),元素后移语句执行n次,时间复杂度O(n)
平均情况:假设Pi(Pi=1/(n+1))是在第i个位置上插入一个结点的概率,则在长度为n的线性表中插入一个结点时,所需移动节点的平均次数为n/2,所以平均时间复杂度O(n)

(2)删除操作
删除顺序表L中第i(1≤i≤L.length)个位置的元素,若成功则返回true,并将被删除的元素用引用变量e返回,否则返回false。
代码:

# include <stdio.h>
# define MaxSize 50

// 定义结构体 
typedef struct{  
	int data[MaxSize] = {1,2,3,4,5,6,7,8,9,10};
	int length = 10;
}SqList;

// 函数声明
void PrintList(SqList L);
bool ListDelete(SqList &L,int i,int &e); 
 
int main (void){
	SqList L;
	int e; // 用于保存删除的值 
	PrintList(L);  // 删除之前的的序列 
	if(!ListDelete(L,4,e)){
		printf("\n删除失败!");
	}else{
		printf("\n删除成功,值为%d!\n",e);
		PrintList(L);  // 删除之后的序列 
	} 
		
	return 0;
} 

// 删除顺序表中第i个位置的元素,若成功则返回true,并将被删除的元素值放在e中返回
bool ListDelete(SqList &L,int i,int &e){  
	if(i<1 || i>L.length)    // 判断i的范围是否有效 
		return false;
	e = L.data[i-1];
	for(int j = i; j< L.length; j++){ // 依次前移一位 
		L.data[j-1] = L.data[j];
	} 
	L.length--;
	return true; 
} 

// 依次输出顺序表的所有元素
void PrintList(SqList L){
	for(int i = 0; i < L.length; i++){
		printf("--%d",L.data[i]);
	}
} 

最好情况:删除表尾元素(即 i=n),无须移动元素,时间复杂度O(1)
最坏情况:删除表头元素(即 i=1),需要移动除第一个以外的所有元素,时间复杂度O(n)
平均情况:假设Pi(Pi = 1/n),每次删除需要移动(n-i)个元素,平均次数为(n-1)/2,所以,平均时间复杂度为O(n)

(3)按值查找(顺序查找)
在顺序表L中查找第一个元素值等于e的元素,并返回其位序(不是数组下标)
修改需要传顺序表L的地址,即修改要传引用、查找不用传引用
代码:

# include <stdio.h>
# define MaxSize 50

// 定义结构体
typedef struct {
	int data[MaxSize]={1,2,3,4,5,6,7,8,9,10};
	int length = 10;
}SqList;
 
// 声明函数
int LocateElem(SqList L,int e); 
 
int main (void){
	SqList L; 
	int i = LocateElem(L,1);
	if(i){
		printf("查找的是%d号元素!",i);
	}else{
		printf("没有查找到!");
	}
	return 0;
} 

// 在顺序表L中查找第一个值等于e的元素,并返回其位序(不是下标值) 
int LocateElem(SqList L,int e){
	for(int i = 0; i < L.length; i++){
		if(L.data[i] == e)
			return i+1;	 
	}
	return 0;    
}

最好情况:查找的元素就是表头,仅需比较一次,时间复杂度为O(1)
最坏情况:查找的元素在表尾(或不存在)时,时间复杂度为O(n)
平均情况:假设Pi(Pi = 1/n)是查找的元素在第i个位置的概率,则平均次数为(n+1)/2,所以,平均时间复杂度为O(n)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!