一:顺序表——静态实现
1.头文件
#include <iostream>
2.定义
//顺序表的实现——静态分布
#define MaxSize 10//定义最大长度
typedef struct {//顺序表的定义
int data[MaxSize];//定义一个静态的整型数组来存放数据元素
int length;//定义length接受表长--即该表当前实际存储数据长度
}SqList;//用typedef函数重命名
3.初始化
//基本操作——初始化一个顺序表 InitList(&L)
void InitList(SqList &L){//改定义中产生的元素变化要带回主函数,所以用引用&
for(int i=0;i<MaxSize;i++)
L.data[i]=0;//依次访问改数组内的元素,并设置为0,以防有脏数据存在
L.length=0;//初始长度定为0
}
4.主函数
int main() {
SqList L;//声明一个顺序表
InitList(L);//初始化刚刚声明的顺序表——此处无需引用符号
for(int i=0;i<MaxSize;i++)//尝试违规打印整个data数组,我们不应该从头访问到尾
//for(int i=0;i<length;i++)//应该访问实际length长度即可,但最好是用基本操作法来访问
printf("data[%d]=%d\n",i,L.data[i]);
return 0;
}
运行结果:
data[0]=0
data[1]=0
data[2]=0
data[3]=0
data[4]=0
data[5]=0
data[6]=0
data[7]=0
data[8]=0
data[9]=0进程已结束,退出代码为 0
二:顺序表——动态实现
1.定义
//顺序表的实现——动态分配
#define InitSize 3//默认的最大长度
typedef struct {
int *data;//指示动态分配数组的指针
int MaxSize;//顺序表的最大容量
int length;//顺序表的当前长度
}SeqList;
2.初始化
//基本操作——初始化一个顺序表 InitList(&L)
void InitList(SeqList &L){
//用malloc函数申请一片连续的存储空间
L.data=(int *) malloc(InitSize*sizeof(int));
//将数组的L指针指向申请到的连续空间的首地址
L.length=0;
L.MaxSize=InitSize;
for(int i=0;i<L.MaxSize;i++)//将所有元素设为默认值
L.data[i]=0;
}
3.增加最大长度
//比较复杂,本质是申请一片新的空间然后复制过去
//增加顺序表的最大长度
void IncreaseSize(SeqList &L,int len){
int *p=L.data;//新建一个指针p指向原数组的头数据地址
L.data=(int *) malloc((L.MaxSize+len)*sizeof(int));
//用malloc申请一片新的连续空间,将头指针指向新申请的空间
for(int i=0;i<L.MaxSize;i++){//将原数组内数据复制到新空间
L.data[i]=p[i];}
for(int i=L.MaxSize;i<L.MaxSize+len;i++){//将剩余所有元素设为默认值
L.data[i]=0;}
L.MaxSize=L.MaxSize+len;//顺序表最大的长度增加len
free(p);//每次用malloc都是重新申请了一片连续的空间,所以要释放原来的空间
}
4.按位插入
//在顺序表中位序i处插入数据e
//时间复杂度:最佳O(1),最坏O(n),平均O(n)
bool ListInsert(SeqList &L,int i,int e){
if(i<1||i>L.length+1)//判断i的范围是否有效,i只能到1-length+1
return false;
if(L.length>=L.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;
}
5.按位删除
//删除顺序表L中的第i个元素,并用e返回删除的元素的值
//时间复杂度:最佳O(1),最坏O(n),平均O(n)
bool ListDelete(SeqList &L,int i,int &e){
if(i<1||i>L.length)//判断i的范围是否有效,i只能到1-length
return false;
e=L.data[i-1];//将即将被删除的元素赋值给e
for(int j=i;j<=L.length;j++)//将第i+1位序(即被删除的后一元素)往前移1位
L.data[j-1]=L.data[j];
L.length--;
return true;
}
6.按位查找
//顺序表的按位查找
//时间复杂度:O(1)
int GetElem(SeqList L,int i){//输入顺序表名和位序
return L.data[i-1];// 以数组获取的方式返回第i-1索引值的顺序表值
}
7.按值查找
//顺序表的按值查找 ->在顺序表中查找第一个值为e的元素,并打印出其位序
//时间复杂度:最佳O(1),最坏O(n),平均O(n)
int LocateElem(SeqList L,int e){
for(int i=0;i<L.length;i++){//在顺序表的实际长度中依次查询
if(L.data[i]==e)//int char double float等可以用==,结构体要依次对比每一个分量
return i+1;
}
return 0;
}
8.主函数
int main() {
system("chcp 65001");//输出中文
SeqList L;//声明一个顺序表
InitList(L);//初始化刚刚声明的顺序表——此处无需引用符号
ListInsert(L,1,23);//此处的i=1是指第一个元素,非下标1
ListInsert(L,2,45);
ListInsert(L,3,67);
printf("\n%*s\n",40,"----尝试违规打印整个初始data数组----");
for(int i=0;i<L.MaxSize;i++)//尝试违规打印整个data数组
printf("data[%d]=%d\n",i,L.data[i]);
IncreaseSize(L,2);
printf("\n%*s\n",40,"----打印添加长度后的整个data数组----");
for(int i=0;i<L.MaxSize;i++)//尝试违规打印整个data数组
printf("data[%d]=%d\n",i,L.data[i]);
printf("\n%*s\n",40,"----调用删除元素函数----");
int e=0;//定义一个变量e接受删除的元素
if(ListDelete(L,6,e))
{printf("已删除第1个元素,删除元素值为=%d\n",e);}
else{
printf("位序不合法,删除失败\n");
}
printf("\n%*s\n",40,"----打印删除元素后的data数组----");
for(int i=0;i<L.MaxSize;i++)//尝试违规打印整个data数组
printf("data[%d]=%d\n",i,L.data[i]);
printf("\n%*s\n",40,"----调用按位查找函数----");
printf("所查询的元素为:%d\n",GetElem(L,2));
printf("\n%*s\n",40,"----调用按值查找函数----");
printf("你所查询的值在第%d位\n",LocateElem(L,45));
return 0;
}
运行结果:
Active code page: 65001
----尝试违规打印整个初始data数组----
data[0]=23
data[1]=45
data[2]=67----打印添加长度后的整个data数组----
data[0]=23
data[1]=45
data[2]=67
data[3]=0
data[4]=0----调用删除元素函数----
位序不合法,删除失败----打印删除元素后的data数组----
data[0]=23
data[1]=45
data[2]=67
data[3]=0
data[4]=0----调用按位查找函数----
所查询的元素为:45----调用按值查找函数----
你所查询的值在第2位进程已结束,退出代码为 0