关于顺序表:1.顺序表的是用连续的存储单元依次存储数据元素
2.逻辑上相邻的两个元素在物理位置上也相邻
3.顺序表的任意一个元素都可以随机存取,随机存取和访问类似
顺序表的优点:1.存储密度大
2.可以进行随机访问
顺序表的缺点:1.元素的插入和删除需要移动大量的元素,
插入:如果说插入到第一个位置,需要移动n个元素,如果说插入到表尾,需要移动0 个元素,平均需要移动n/2个元素
删除:如果说删除第一个元素则需要移动i-1个元素,如果说删除最后一个元素,则需要 移动0个元素,平均需要移动(n-1)/2个元素
查找:平均需要移动(n+1)/2个元素
注:这里得到的式子并不是通过首尾相加除以2,而是通过计算数学期望所得
2.顺序表的存储分配需要一段连续的存储空间,不够灵活
对于静态的顺序表,他的空间从一开始就是固定的,一旦空间被占满就会产生溢出
还有一种是动态的顺序表,一旦空间被占满就会重新开辟一整块更大的存储空间, 将原来表中的数据全部拷贝到新空间
以下是顺序表所有的操作,包括初始化,插入删除查找。
#include <stdio.h>
//1.顺序表的结构体,其内容有数据表的元素data[Maxsize]以及顺序表的当前长度length,以及定义了顺序表的最大长度Maxsize
#define Maxsize 50 //定义线性表的最大长度
typedef struct{
int data[Maxsize]; //顺序表的元素
int length; //顺序表的当前长度,注意这里是当前长度
}sqlist; //顺序表的类型定义
//以上为静态顺序表的存储结构
//2.静态顺序表的初始化,由于静态顺序表在声明的时候就已经为其分配了数组空间,所以初始化的时候只需要将数组的长度设置为0
sqlist l; //声明一个顺序表
void Initlist(sqlist &l) //这里的l加了地址符号意味着会对l指针所指向的内容进行改变
{
l.length=0; //声明顺序表的长度为0
}
//3,顺序表的插入(假设插入位置i代表着在第i个位置插入)
//步骤:a.先进行判断,判断插入的位置i是否合法
// b. 然后将从第i个位置以及之后的所有元素往后移动一个位置,空出一个位置给新插入的元素
bool Listinsert(sqlist &l,int i,int e)
{
if(i<1||i>l.length+1) //i最小为1,代表第一个元素,i最大为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; //在第i个位置插入值
l.length++; //顺序表的长度加一
return true;
}
//4.顺序表的删除操作
//步骤:a.先判断插入的位置是否合法
// b.将第i+1个元素及其后面所有元素往前移一位
bool Listdelete(sqlist &l,int i,int &e)//这里的e加上了地址符号,因为后面删除之前要把数值保存给e,这样的话在主函数中就可以用e表示出删除掉的值是多少了
{
if(i<1||i>l.length)
{
return false;
}
if(l.length>Maxsize)
{
return false;
}
e=l.data[i-1]; //将删除的值保存给e
for(int j=i;j<l.length;j++)//最后一个位置下标为length-1根据操作代码可知j不需要等于length
{
l.data[j-1]=l.data[j];
}
l.length--;
return true;
}
//5.顺序表的查找操作
//按值查找(顺序查找)
int LocateElem(sqlist l,int e)//查找相当于访问没有必要对表中的值进行修改,因此没有加地址符号&
{
int i;
for(i=0;i<l.length;i++)
{
if(l.data[i]==e)
{
return i+1;
}
}
return 0;
}
int main()
{
int a,b;
Initlist(l);
printf("此时表的长度为%d,",l.length);
printf("请对顺序表进行插入\n");
printf("请输入插入的值:");
scanf("%d",&a);
printf("请输入插入到第几个元素:");
scanf("%d",&b);
if(Listinsert(l,b,a))
{
printf("插入成功\n");
printf("打印顺序表内容:\n");
printf("顺序表的长度为%d\n",l.length);
for(int j=0;j<l.length;j++)
{
printf("第%d个元素为:%d\n",j+1,l.data[j]);
}
}
else printf("插入失败,插入的位置不合法\n");
//查找
printf("输入要查找的值:\n");
scanf("%d",&a);
if(LocateElem(l,a)!=0) printf("该值是第%d个元素\n",LocateElem(l,a));
else printf("表中无该元素\n");
//删除
printf("接下来是对表进行删除:\n");
printf("请输入删除第几个元素:");
scanf("%d",&b);
if(Listdelete(l,b,a))
{
printf("删除成功\n");
printf("打印顺序表内容:\n");
printf("顺序表的长度为%d\n",l.length);
}
else printf("删除的位置不合法");
}
顺序表的动态存储,存储结构依旧是顺序结构而不是链式结构,物理结构没有变化,依旧是随机存取方式,只是分配的空间大小可以在运行时决定
#include <stdio.h>
#define Initsize 100 //表长度的初始定义
typedef struct {
int *data; //指示动态分配数组的指针
int Maxsize,length; //数组的最大容量和当前个数
}sqlist;
//初始化
void Initlist(sqlist &l)
{
l.data=(int *)malloc(Initsize*sizeof(int));//分配存储空间
l.length=0;//顺序表的初始长度
l.Maxsize=Initsize;//初始存储最大量
}