顺序表是线性表的一种存储结构,它使用一组地址连续的存储单元依次存储线性表中的数据元素。
基本概念
物理结构:顺序表中的元素在内存中是连续存储的
逻辑关系:通过物理上的相邻关系表示逻辑上的前驱后继关系
随机访问:可以通过首地址和元素序号(下标)在O(1)时间内访问任意元素
实现方式:顺序表的头插、尾插、指定插入、指定删除、遍历实现方式如下:
*@file name:顺序表实现
*@brief :实现顺序表的头插、尾插、指定插入、指定删除、遍历。
*@author :RISE_AND_GRIND@163.com
*@date :2025/01/07
*@version :1.0:版本
*@property :
*@note :
* CopyRight (c)2023-2024 RISE AND GRIND@163.com All Right Reseverd
*****************************************************************/
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
typedef int Datatype_t;//将int重名称 ,方便后面改存储类型
/*
*构造记录顺序表sequencelist各项参数(顺序表的首地址+顺序表的容量+顺序表中有效元素的下标)的结构体
*/
typedef struct SequenceList
{
Datatype_t * Addr; //记录顺序表首地址
unsigned int Size; //记录顺序表的容量
int Last; //记录顺序表的最后元素位置
}Seqlist_t;
/*
@function name :Seqlist_Creat
@brief :创建顺序表并对顺序表进行初始化
@param :形参为需要创建的顺序表的长度,单位是字节
@retval :返回顺序表的首地址
@date :2025/02/07
@version :1.0:版本
@note :
*/
Seqlist_t *Seqlist_Creat(unsigned int size)
{
Seqlist_t *Manager = (Seqlist_t *)calloc(1,sizeof(Manager));//利用calloc为顺序表的管理结构体申请一块堆内存
//判断存储顺序表首地址的空间是否申请成功
if(Manager == NULL)
{
perror("calloc head failed");
exit(-1); //程序异常种终止
}
Manager->Addr = (Datatype_t *)calloc(size,sizeof(Datatype_t));//申请成功则再申请顺序表空间
//判断是否申请顺序空间成功
if(Manager->Addr == NULL)
{
perror("Creat Seqlist failed");
free(Manager);
exit(-1); //程序异常种终止
}
Manager->Size=size;//对管理顺序表的结构体进行容量初始化(元素容量+最后元素下标)
Manager->Last =-1; //由于顺序表为空,则最后元素下标值为-1;
return Manager ; //返回顺序表的首地址
}
/*
@function name :Seqlist_IsFull
@brief :判断顺序表是否存储满
@param :形参为顺序表的首地址
@retval :返回判断结果,true表示顺序表存储满了,false表示未存储满
@date :2025/02/07
@version :1.0:版本
@note :
*/
bool Seqlist_IsFull(Seqlist_t *Manager)
{
return (Manager->Last+1 == Manager->Size)? true :false; //若顺序表的尾指针+1和顺序表的大小相等,则返回true,反之返回false
}
/*
@function name :Seqlist_TaiAdd
@brief :向顺序表中尾部加入元素
@param :形参分别是顺序表的首地址、需要插入的数据值
@retval :返回判断结果,true表示数据插入成功,false表示失败
@date :2025/02/07
@version :1.0:版本
@note :
*/
bool Seqlist_TaiAdd(Seqlist_t *Manager,Datatype_t Data)
{
//判断顺序表是否已满
if (Seqlist_IsFull(Manager))
{
printf("Seqlist is full\n");
return false;
}
Manager->Addr[++Manager->Last] =Data;//如果顺序表有空闲空间,则把新元素添加到顺序表尾部
return true;
}
/*
@function name :Seqlist_HeadAdd
@brief :向顺序表中头部加入元素
@param :形参分别是顺序表的首地址、需要插入的数据值
@retval :返回判断结果,true表示数据插入成功,false表示失败
@date :2025/02/07
@version :1.0:版本
@note :
*/
bool Seqlist_HeadAdd(Seqlist_t *Manager,Datatype_t Data)
{
//判断顺序表是否已满
if (Seqlist_IsFull(Manager))
{
printf("Seqlist is full\n");
return false;
}
//若顺序表有空间,则向头部插入,数据都向后挪动
for(int i=Manager->Last;i>=0;i--)
{
Manager->Addr[i+1] = Manager->Addr[i];
}
Manager->Addr[0] =Data; //把数据插入头部
Manager->Last++ ; //将尾指针指向尾部,方便后面使用
return true;
}
/*
@function name :Seqlist_IsEmpty
@brief :判断顺序表是否为空
@param :形参为顺序表的首地址
@retval :返回判断结果,true表示顺序表为空,false表示顺序表不为空
@date :2025/02/07
@version :1.0:版本
@note :
*/
bool Seqlist_IsEmpty(Seqlist_t *Manager)
{
return (Manager->Last==-1)? true : false;//若顺序表的尾指针为-1,则顺序表为空,返回true,否则返回false
}
/*
@function name :Seqlist_Print
@brief :遍历并查看顺序表中是否存在需要的数据
@param :形参为顺序表的首地址、查询的数据值
@retval :返回数据在顺序表中位置,不存在就返回-1
@date :2025/02/07
@version :1.0:版本
@note :
*/
int Seqlist_Print(Seqlist_t *Manager,Datatype_t Data)
{
//循环判断数据是否存在,存在就返回数据存在的位置
for(int i=0 ;i<=Manager->Last; i++)
{
if(Manager->Addr[i]== Data )
return i;
}
return -1;
}
/*
@function name :Seqlist_Del
@brief :删除顺序表中指定的数据
@param :形参为顺序表的首地址、需要删除的数据值
@retval :返回删除结果,true表示删除成功,false表示删除失败
@date :2025/02/07
@version :1.0:版本
@note :
*/
bool Seqlist_Del(Seqlist_t *Manager,Datatype_t Data)
{
//判断顺序表是否为空
if(Seqlist_IsEmpty(Manager))
{
printf("Seqlist is empty");
return false;
}
//此时需要查找目标值是否在顺序表中,在就执行删除,不在就提示
if(Seqlist_Print(Manager, Data)==-1)
{
printf("Not in Seqlist\n");
return false ;
}
else
{
//i等于找出的需要删除的数据的位置,将后面的数据前移一位,覆盖掉需要删除的数据
for(int i=Seqlist_Print(Manager, Data);i<Manager->Last;i++)
{
Manager->Addr[i] = Manager->Addr[i+1];
}
Manager->Last-- ; //将尾指针重新指向尾部,方便后面使用
printf("del successful\n");
return true;
}
}
/*
@function name :main
@brief :主函数,执行函数调用
@param :
@retval :
@date :2025/02/07
@version :1.0:版本
@note :
*/
int main()
{
Seqlist_t *Manager = Seqlist_Creat(15); //创建顺序表,包括15个数据位
//向顺序表中写入需要存储的数据
for(int i=0;i<10;i++)
{
Manager->Addr[i] =i;
Manager->Last++;
}
Seqlist_HeadAdd(Manager,10); //向顺序表的头部插入数据10
Seqlist_TaiAdd(Manager,11); //向顺序表的尾部插入数据11
Seqlist_Del(Manager,7); //删除顺序表中的7
//最后输出显示顺序表中的数据
for(int i=0;i<=Manager->Last;i++)
{
printf("%d\n",Manager->Addr[i]) ;
}
return 0;
}
运行结果如图:
评论区