顺序存储
逻辑位置和内存中的物理位置相同,除第一个外都有且仅有一个直接前驱,除最后一一个元素外有且仅有一个直接后继。
*优点:
- 存储密度大,
- 存储空间利用率高,
- 可以实现随机存取,即直接通过地址访问元素
缺点:
- 插入和删除操作需要在物理上移动大量元素,这可能会导致效率低下,
- 需要预先分配连续的存储空间,这可能导致存储空间的浪费
综上:这种结构适合于频繁查找和访问元素的场景
代码实现
定义顺序表
#define MaxSize 100
typedef int DataType; //将DataType 设为int型
typedef struct
{
DataType data[MaxSize ]; // int data[100]
int length; //表示当前长度
}SeqList; //结构体的别名,引用Seqlist=引用上述结构体
初始化
void InitSeqList(SeqList *L)
{
L->length=0;
}
求表长
int GetLength(SeqList *L)
{
return L->length;
}
按位查找
时间复杂度 O(1)
int GetElem(SeqList *L, int i, DataType *x)
{ /*获取顺序表中第i位中元素函数*/
if (i<1 || i>L->Length)
return 0;
else
{
*x = L->data[i-1]; //返回元素值
return 1;
}
}
按值查找
时间复杂度O(n)
ASL(平均查找长度): (n+1)/2
int Locate(SeqList *L,DataType x)
{
int j=0;
while(j<L->length && L->data[j]!=x)
j++;
if(j>=L->length)
return 0;
else
return j+1; /*返回的是元素位置*/
}
插入
- 判表满
- 判插入位置是否规范
- 后续元素循环后移
- 插入元素
- 表长+1
时间复杂度O(n)
ASL(平均查找长度): n/2
int InsElem(SeqList *L,int i,DataType x) /*插入位置i 插入元素x*/
{
int j;
if(L->length >= MaxSize) //判表满
{
printf("顺序表已满");
return -1;
}
if(i<1 || i > L->length+1)
{
printf("插入位置错");
return 0;
}
for (j=L->Length-1; j>=i-1; j--) /*结点移动*/
L->data[j+1]=L->data[j];
L->data[i-1]=x; /*新元素插入*/
L->Length++; /*顺序表长度增1 */
return 1; /*插入成功,返回*/
}
删除
- 判表空
- 判删除位置
- 后续元素前移
- 表长-1
时间复杂度: O(n)
ASL: (n-1)/2
int DelElem (SeqList *L, int i, DataType *x)
{ /*在顺序表L中删除第i位元素函数*/
int j;
if (L->Length==0)
{ printf ("顺序表为空!");
return 0; /*表空,不能删除*/
}
if (i<1 || i>L->Length) /*检查是否空表及删除位置的合法性*/
{ printf ("不存在第i个元素");
return 0;
}
*x= L->data[i-1]; /*用指针变量*x返回删除的元素值*/
for(j=i;j<L->Length;j++)
L->data[j-1]=L->data[j]; /*结点依次前移*/
L->Length--; /*顺序表长度减1*/
return 1; /*删除成功,返回*/
}
完整示例(C语言实现):
/*顺序表的各种操作程序*/
#include <stdio.h>
#include <stdlib.h> // 包含stdlib.h以使用malloc
#define MAXLEN 100 /*定义常量MAXLEN为100表示存储空间总量*/
typedef int DataType; /*定义ElemType为int类型*/
typedef struct /*顺序表存储类型*/
{ /* DataType data[MAXLEN]; 存放线性表的数组*/
DataType *data;
int Length; /*Length是顺序表的长度*/
}SeqList;
void InitList( SeqList *L )
{ /*初始化顺序表L函数*/
L->Length=0; /*初始化顺序表为空*/
}
void CreateList(SeqList *L,int n)
{ /*建立顺序表并输入多个元素函数*/
int i;
L->data = (DataType *)malloc(sizeof(DataType) * n);
if(!L->data)
puts("error");
printf("请输入%d个整数:",n);
for(i=0;i<n;i++)
scanf("%d",&L->data[i]);
L->Length=i; /*设线性表的长度为i*/
}
int GetElem(SeqList *L, int i, DataType *x)
{ /*获取顺序表中第i位中元素函数*/
if (i<1 || i>L->Length)
return 0;
else
{
*x = L->data[i-1];
return 1;
}
}
int Locate(SeqList *L, DataType x)
{ /*在顺序表L中定位元素x函数*/
int i=0;
while(i<L-> Length && L->data[i]!= x)
i++;
if (i>=L->Length)
return 0;
else
return i+1; /*返回的是元素位置*/
}
int InsElem(SeqList *L, int i, DataType x)
{ /*在顺序表L中在第i位中插入新元素x函数*/
int j;
if (L->Length>=MAXLEN)
{ printf ("顺序表已满!");
return -1; /*表满,不能插入*/
}
if (i<1 || i>L->Length+1) /*检查给定的插入位置的正确性*/
{ printf("插入位置出错!");
return 0;
}
if (i == L->Length+1)
{ L->data[i-1]=x;
L->Length++;
return 1; /*插入的位置为表尾,则不需移动直接插入即可*/
}
for (j=L->Length-1; j>=i-1; j--) /*结点移动*/
L->data[j+1]=L->data[j];
L->data[i-1]=x; /*新元素插入*/
L->Length++; /*顺序表长度增1 */
return 1; /*插入成功,返回*/
}
int DelElem (SeqList *L, int i, DataType *x)
{ /*在顺序表L中删除第i位元素函数*/
int j;
if (L->Length==0)
{ printf ("顺序表为空!");
return 0; /*表空,不能删除*/
}
if (i<1 || i>L->Length) /*检查是否空表及删除位置的合法性*/
{ printf ("不存在第i个元素");
return 0;
}
*x= L->data[i-1]; /*用指针变量*x返回删除的元素值*/
for(j=i;j<L->Length;j++) /*结点移动*/
L->data[j-1]=L->data[j];
L->Length--; /*顺序表长度减1*/
return 1; /*删除成功,返回*/
}
void DispList(SeqList *L)
{ /*显示输出顺序表L的每个元素函数*/
int i;
for(i=0;i< L->Length;i++)
printf("%5d ", L->data[i]);
}
void Menu()
{ /*显示菜单子函数*/
printf("\n 顺序表的各种操作");
printf("\n==================================================");
printf("\n| 1——建立顺序表 |");
printf("\n| 2——插入元素 |");
printf("\n| 3——删除元素 |");
printf("\n| 4——按位置查找元素 |");
printf("\n| 5——按元素值查找其在表中位置 |");
printf("\n| 6——求顺序表的长度 |");
printf("\n| 0——返回 |");
printf("\n==================================================");
printf("\n请输入菜单号(0-6):");
}
main()
{
SeqList L;
DataType x;
int n,i,loc;
char ch1,ch2,a;
ch1='y';
while(ch1=='y'||ch1=='Y')
{ Menu();
scanf("%c",&ch2);
getchar();
switch(ch2)
{
case '1':
InitList( &L );
printf("请输入建立线性表的个数:");
scanf("%d",&n);
CreateList(&L,n);
printf("建立的线性表为:");
DispList(&L);
break;
case '2':
printf("请输入要插入的位置:");
scanf("%d",&i);
printf("请输入要插入的元素值:");
scanf("%d",&x);
if(InsElem(&L,i,x))
{
printf("已成功在第%d的位置上插入%d,插入后的线性表为:\n",i,x);
DispList(&L);
}
else
printf("输入插入的参数错误!");
break;
case '3':
printf("请输入要删除元素的位置:");
scanf("%d",&i);
if(DelElem (&L, i, &x))
{
printf("已成功在第%d的位置上删除%d,删除后的线性表为:\n",i,x);
DispList(&L);
}
else
printf("\n输入删除的参数错误!");
break;
case '4':
printf("请输入要查看表中元素位置(从1开始):");
scanf("%d",&i);
if(GetElem(&L, i, &x))
printf("当前线性表第%d个元素的值为:%d",i,x);
else
printf("输入的位置错误!");
break;
case '5':
printf("请输入要查找的元素值为:");
scanf("%d",&x);
loc=Locate(&L, x);
if(loc)
printf("查找元素值为%d的位置为:%d",x,loc);
else
printf("该表中无此元素!");
break;
case '6':
printf("当前线性表的长度为:%d",L.Length);
break;
case '0':
ch1='n';break;
default:
printf("输入有误,请输入0-4进行选择!");
}
if(ch2!='0')
{ printf("\n按回车键继续,按任意键返回主菜单!\n");
a=getchar();
if(a!='\xA')
{
getchar();ch1='n';
}
}
}
}
结语
敬请各位大佬批评指正 日后也会持续更新数据结构相关内容,互相学习😊😊