介于作者水平的问题,文中可能会有这样或者那样的错误或者漏洞,欢迎指正
下一篇写动态顺序表,并做一些对比

一、线性表的分类

线性表主要分成有两种存储结构1、顺序存储结构(静态表,动态表),2、链式存储结构

请添加图片描述

1.详细版本思维导图

请添加图片描述
这里有高清版版本

1、顺序表

1.1静态顺序表

使用一组连续的存储单元来依次存放线性表中的,基本上可以理解为一维数组,所以也就具有数组的性质,实现了快速存取,但是缺点也是十方明显的就是插入删除移动可能会移动大量数据,同样难以估计存储空间,但是区别点也是有的,线性表的长度是指现在其中元素的个数,数组的长度是指线性表的最大长度

接下来使用一段代码来完成上图中的代码
(若是至于参数什么时候是&L(需要对L中元素进行修改的时候),什么时候是L(只是查看))

1、InitList(&L):初始化一个空的线性表

status InitList(SqList* L) { //相当于是给上面的结构体赋一个初值
	L->length=0;
	return OK;
}

这里没有给数组元素进行赋值0的操作,但是其实却也是不影响的,因为下面的操作都是使用L.length来对数据元素进行操作的,所以不会访问到没有给值的数组元素
并且注意虽然有的编译器会将int类型的变量赋初始值为零,但是有的编译器确不会进行赋值的呦

2、Length(L):求表长,返回线性表L的长度

status Length(SqList L) {
	return L.length;
}

3、LocateElem(L,e):按值查找操作,即获取表L中具有给定关键字值的元素

int LocateElem(SqList L,ElemType e) {
	F(i,0,L.length) {
		if(e==L.data[i])
			return ++i;
	}
	printf("未找到这个值");
	return 0;
}

4、GetElem(L,i):按位查找操作,获取L中第i个位置上的元素的值**

ElemType GetElem(SqList L,int i) { //因为是获取第i个位置上,所以不用取等号
	if(L.length<i||i<0) {
		printf("你所输入的位置信息不对"); 
		return 0;
	}
	else return L.data[i-1];
}

这里若是要提高健壮性的话,这里可以加一个判断i的位置是否合法,

5、ListInsert(&L,i,e):

插入操作,在表L中第i个位置插入指定元素,这里的i指的是位序

status ListInsert(SqList *L,int i,ElemType e) {
	/*要想实现修改顺序表,就需要移动其中的数据*/ 
	if(i<1||i>L->length+1) {
		printf("你的输入有问题");
		return ERROR;
	}
	//因为表示的插入的位置[1,L.length+1] 可以在;最后一个位置的后一个位置插入
	 else if(MAX==L->length){
		printf("此时已经超过最大容积\n");
		return ERROR;
	}
	/*因为顺序表的最大容积是确定的,所以需要加一个是否已经满的判断*/
	else {
		if((L->length+1)==i) { //插入最后一个元素就不需要移动
			L->data[i-1]=e;
		} 
		else { //否则就需要移动
			for(int j=L->length-1; j>=i-1; j--) {
				/*第一只能从尾部向前来移动 否则就会发生数据 覆盖,
				 我们要插入i位置就需要数组的i-1空出来,所以i-1也要移动*/
				L->data[j+1]=L->data[j];	
			}
			L->data[i-1]=e;
		}
		L->length++;
	}
	return OK;
}

6、PrintList(L):输出操作,按照前后 顺序输出线性表L的所有元素的值

status PrintList(SqList L) {
	cout<<"数组L此时的内容是"<<endl;
	for(int i=0; i<L.length; i++)
		cout<<L.data[i]<<" ";
	cout<<endl;
	return OK;

7、Empty(L):判空操作:若是L为空表,返回true,否则返回false

status Empty(SqList L) {
	if(0==L.length) return OK;
	else return ERROR;
}

8、DestoryList(&l):销毁操作,销毁线性表**,

status DestoryList(SqList *L) {
	L->length=0;
	PrintList(*L); 
}

9、ListDelete(SqList *L,int i)删除顺序表中指定位置的值

status ListDelete(SqList *L,int i){//删除顺序表中指定位置的值 
	if(i<1||i>L->length){
		cout<<"此时的i的值是"<<i; 
		cout<<"你输入的区间不正确"<<endl; 
		return ERROR;
	} 
	else{//区间正确,直接时候后面一个元素覆盖前一个元素即可  
		for(int j=i;j<L->length;j++){//要考虑边界值,这里边界值没有问题 
			L->data[j-1]=L->data[j];
		}
		L->length--;
		cout<<"成功删除!"<<endl; 
		PrintList(*L); 
		return OK;
	}
}

可实现代码汇总(使用上述函数实现了增删改查)

//InitList(&L):初始化一个空的线性表
//Length(L):求表长,返回线性表L的长度,即即L中数据元素的个数
//LocateElem(L,e):按值查找操作,即获取表L中具有给定关键字值的元素
//GetElem(L,i):按位查找操作,获取L中第i个位置上的元素的值
//ListInsert(&L,i,e):插入操作,在表L中第i个位置插入指定元素
//ListDelete(SqList *L,int i)删除顺序表中指定位置的值*
//PrintList(L):输出操作,按照前后 顺序输出线性表L的所有元素的值
//Empty(L):判空操作:若是L为空表,返回true,否则返回false
//DestoryList(&l):销毁操作,销毁线性表
//考试的时候最好也是使用这些名称

#include<bits/stdc++.h>
#define MAX 10
#define ElemType int
#define status int
#define OK  1
#define ERROR 0
#define F(i,m,n) for(int i=m;i<n;i++)
using namespace std;
/********************功能函数*************************/ 
typedef struct {
	ElemType data[MAX];
	int length;
} SqList;
status PrintList(SqList L) {
	cout<<"数组L此时的内容是"<<endl;
	for(int i=0; i<L.length; i++)
		cout<<L.data[i]<<" ";
	cout<<endl;
	return OK;
}
status InitList(SqList* L) { //相当于是给上面的结构体赋一个初值
	L->length=0;
	return OK;
}
status Length(SqList L) {
	return L.length;
}
int LocateElem(SqList L,ElemType e) {
	F(i,0,L.length) {
		if(e==L.data[i])
			return ++i;
	}
	printf("未找到这个值");
	return 0;
}
ElemType GetElem(SqList L,int i) { //因为是获取第i个位置上,所以不用取等号
	if(L.length<i||i<0) {
		printf("你所输入的位置信息不对"); 
		return 0;
	}
	else return L.data[i-1];
}
status ListInsert(SqList *L,int i,ElemType e) {
	/*要想实现修改顺序表,就需要移动其中的数据*/ 
	if(i<1||i>L->length+1) {
		printf("你的输入有问题");
		return ERROR;
	}
	//因为表示的插入的位置[1,L.length+1] 可以在;最后一个位置的后一个位置插入
	 else if(MAX==L->length){
		printf("此时已经超过最大容积\n");
		return ERROR;
	}
	/*因为顺序表的最大容积是确定的,所以需要加一个是否已经满的判断*/
	else {
		if((L->length+1)==i) { //插入最后一个元素就不需要移动
			L->data[i-1]=e;
		} 
		else { //否则就需要移动
			for(int j=L->length-1; j>=i-1; j--) {
				/*第一只能从尾部向前来移动 否则就会发生数据 覆盖,
				 我们要插入i位置就需要数组的i-1空出来,所以i-1也要移动*/
				L->data[j+1]=L->data[j];	
			}
			L->data[i-1]=e;
		}
		L->length++;
	}
	return OK;
}
status ListDelete(SqList *L,int i){//删除顺序表中指定位置的值 
	if(i<1||i>L->length){
		cout<<"此时的i的值是"<<i; 
		cout<<"你输入的区间不正确"<<endl; 
		return ERROR;
	} 
	else{//区间正确,直接时候后面一个元素覆盖前一个元素即可  
		for(int j=i;j<L->length;j++){//要考虑边界值,这里边界值没有问题 
			L->data[j-1]=L->data[j];
		}
		L->length--;
		cout<<"成功删除!"<<endl; 
		PrintList(*L); 
		return OK;
	}
}
status Empty(SqList L) {
	if(0==L.length) return OK;
	else return ERROR;
}
status DestoryList(SqList *L) {
	L->length=0;
	PrintList(*L); 
}
/**************************操作函数*****************************/
/*写操作函数的时候就尽量避免使用内部*/ 
void Add(SqList *L){
	cout<<"1、你是要增加一系列数,2、还是在某一个位置增加一个数"<<endl;
	int choice; 
	cin>>choice;int i=1;int size;ElemType val;
	switch(choice){
		case 1:{
			cout<<"请输入你要添加多少个元素 添加的值是多少"<<endl;
			scanf("%d%d",&size,&val);
			while(size--){
				ListInsert(L,i++,val);
			} 
			PrintList(*L);
			break;
		} 
		case 2:{
			cout<<"请输入某一个位置,以及某一个值"<<endl;
			cin>>size>>val;
			ListInsert(L,size,val);
			PrintList(*L); 
			break;
		}
		default:{
			break;
		}
	}
}
void Delete(SqList* L){
	int flag;int size;
	cout<<"1、删除某个位置,2、销毁向量"<<endl; 
	cin>>flag;
	if(1==flag){
		cout<<"请输入你要删除的位置"<<endl;
		cin>>size;
		ListDelete(L,size);
	} 
	else if(2==flag){
		DestoryList(L);
	}
	else{
		cout<<"你的输入不正确"<<endl; 
	}
}
void Modify(SqList*L){//修改某个值为某  只修改第一个 
	ElemType val1,val2; 
	cout<<"请输入你想修改的值"<<endl;
	cout<<"请输入你现在想填入的值"<<endl;
	scanf("%d%d",&val1,&val2); 
	int i=LocateElem(*L,val1);
	ListDelete(L,i);
	ListInsert(L,i,val2);
	PrintList(*L);
}
void Seek(SqList L){
	int choice; int val;
	cout<<"1、查找某一个位置的值"<<endl;
	cout<<"2、查找某一个值第一次出现的位置"<<endl;
	cout<<"3、查看是否是空值"<<endl;
	cout<<"4、查看列表的长度"<<endl;
	cin>>choice;
	switch(choice){
		case 1:{
			cout<<"请输入你要查找的位置"<<endl;
			cin>>val; 
			cout<<"你要查找的位置上的值是"<<GetElem(L,val)<<endl; 
			break;
		}
		case 2:{
			cout<<"请输入你要查找的值"<<endl;
			cin>>val;
			cout<<"你要查找的值所在的位置是"<<LocateElem(L,val)<<endl; 
			break;
		} 
		case 3:{
			if(1==Empty(L)) cout<<"是一个空表"<<endl;
			else cout<<"不是一个空表"<<endl; 
			break;
		}
		case 4:{
			cout<<"此时的列表长度是"<<Length(L)<<endl; 
			break;
		}
	}
}
void menu() {
	cout<<"使用上述函数实现增删改查"<<endl;
	cout<<"1、增 2、删除 3、修改 4、查 5、退出"<<endl; 
}
status main() {
	SqList L;int choice; 
	InitList(&L); 
	
	while(1){
		menu();cin>>choice;
		if(5==choice) break; 
		switch(choice){
			case 1:{
				Add(&L);
				break;
			}
			case 2:{
				Delete(&L);
				break;
			}
			case 3:{
				Modify(&L);
				break;
			}
			case 4:{
				Seek(L);
				break;
			}
			default:break;
	} 
	
}
}

请添加图片描述

2、动态顺序表

1.2动态顺序表(可点击跳转)

总结

这里注意若是静态数组越界了,则无法挽救,静态顺序表的长度确定之后,其值无法修改

若是文章对你的提升由哪怕一点帮助的话 请答应我 不要吝啬你的点赞评论 转载请告知哪一部分我检查一下

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐