考研数据结构之静态顺序表
·
介于作者水平的问题,文中可能会有这样或者那样的错误或者漏洞,欢迎指正
下一篇写动态顺序表,并做一些对比
文章目录
- 一、线性表的分类
- 1、顺序表
- 1、InitList(&L):初始化一个空的线性表
- 2、Length(L):求表长,返回线性表L的长度
- 3、LocateElem(L,e):按值查找操作,即获取表L中具有给定关键字值的元素
- 4、GetElem(L,i):按位查找操作,获取L中第i个位置上的元素的值**
- 5、ListInsert(&L,i,e):
- 6、PrintList(L):输出操作,按照前后 顺序输出线性表L的所有元素的值
- 7、Empty(L):判空操作:若是L为空表,返回true,否则返回false
- 8、DestoryList(&l):销毁操作,销毁线性表**,
- 9、ListDelete(SqList *L,int i)删除顺序表中指定位置的值
- 可实现代码汇总(使用上述函数实现了增删改查)
- 2、动态顺序表
- 总结
一、线性表的分类
线性表主要分成有两种存储结构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动态顺序表(可点击跳转)
总结
这里注意若是静态数组越界了,则无法挽救,静态顺序表的长度确定之后,其值无法修改
若是文章对你的提升由哪怕一点帮助的话 请答应我 不要吝啬你的点赞评论 转载请告知哪一部分我检查一下
更多推荐

所有评论(0)