一、顺序存储结构
顺序表,全名顺序存储结构,是线性表的一种。
线性表用于存储逻辑关系为“一对一”的数据,顺序表自然也不例外。
顺序表存储数据时,会提前申请一整块足够大小的物理空间,然后将数据依次存储起来,存储时做到数据元素之间不留一丝缝隙。
例如,使用顺序表存储集合 {1,2,3,4,5},数据最终的存储状态如图 1 所示:
由此我们可以得出,将“具有 ‘一对一’ 逻辑关系的数据按照次序连续存储到一整块物理空间上”的存储结构就是顺序存储结构。
通过观察图 1 中数据的存储状态,我们可以发现,顺序表存储数据同数组非常接近。其实,顺序表存储数据使用的就是数组。
二、顺序表的初始化
使用顺序表存储数据之前,先定义一个结构体:
1.申请足够大小的物理空间;
2. 顺序表的长度,也就是表中存储数据元素的个数;
3. 顺序表申请的存储容量;
一般来说(顺序表申请的存储容量要大于表中存储数据元素的个数)
typedef struct{
int *head; //声明了一个名为 head 的长度不确定的数组,也叫“动态数组”
int length; //记录表中存储数据元素的个数
int size; //记录顺序表分配的存储容量
}tabel;
#define Size 5
tabel initTable()
{
tabel t;
t.head = (int *)malloc(Size*sizeof(int));
if(!t.head)
{
printf("初始化失败");
exit(0);
}
t.length = 0;
t.size = Size;
return t;
}
运行结果:
三、顺序表插入元素
1.判断插入是否有问题
2.做插入操作时,首先需要看顺序表是否有多余的存储空间提供给插入的元素,如果没有,需要申请
3.插入操作,需要将从插入位置开始的后续元素,逐个后移
4.后移完成后,直接将所需插入元素,添加到顺序表的相应位置
例如,在 {1,2,3,4,5} 的第 3 个位置上插入元素 6,实现过程如下:
//插入函数,其中place 为插入到顺序表的位置 ,data 为插入的元素
tabel addTabel(tabel t,int place,int data)
{
//判断插入是否有问题
if(place>t.length+1 ||place <0 )
{
printf("插入的位置有问题\n");
return t;
}
//做插入操作时,首先需要看顺序表是否有多余的存储空间提供给插入的元素,如果没有,需要申请
if(t.length >= t.size)
{
t.head = (int *)realloc(t.head,(t.size+1)*sizeof(int));
if(t.head == NULL)
{
printf("存储分配失败\n");
return t;
}
t.size++;
}
//插入操作,需要将从插入位置开始的后续元素,逐个后移
for(int i=t.length-1;i>=place-1;i--)
{
t.head[i+1] = t.head[i];
}
//后移完成后,直接将所需插入元素,添加到顺序表的相应位置
t.head[place-1] = data;
t.length++;
return t;
}
运行结果:
四、顺序表删除元素
1.判断删除的元素的位置是否正确
2.执行删除操作
从顺序表中删除指定元素,实现起来非常简单,只需找到目标元素,并将其后续所有元素整体前移 1 个位置即可。
后续元素整体前移一个位置,会直接将目标元素删除,可间接实现删除元素的目的
// 顺序表删除元素
tabel delTabel(tabel t,int place)
{
//1.判断删除的元素的位置是否正确
if(place>t.length || place<0)
{
printf("被删除的元素的位置有误!\n");
return t;
}
//2.执行删除操作
for(int i=place;i<t.length;i++)
{
t.head[i-1] = t.head[i];
}
t.length --;
return t;
}
五、顺序表查找元素,返回元素位置
//查找函数,其中,data 表示要查找的数据元素的值
//如果查找成功返回元素的位置
int findTabel(tabel t,int data)
{
for(int i=0;i<t.length;i++)
{
if(t.head[i] == data)
{
return i+1;
}
}
return -1;//如果查找失败,返回-1
}
六、顺序更改元素
// 顺序表更改元素的实现过程是:
// 1. 找到目标元素;
// 2. 直接修改该元素的值;
tabel changeTabel(tabel t,int data,int newdata)
{
int place;//定义需要修改元素的位置,先查找到元素
place = findTabel(t,data);
t.head[place-1] = newdata;//由于返回的是元素在顺序表中的位置,所以place-1 就是该元素在数组中的下标
return t;
}
七、完整顺序表的代码
#include <stdio.h>
#include <stdlib.h>
//顺序表的初始化
// 使用顺序表存储数据之前,先定义一个结构体
// 1.申请足够大小的物理空间之外,
// 2.顺序表的长度,也就是表中存储数据元素的个数;
// 3.顺序表申请的存储容量;
//(提示:正常状态下,顺序表申请的存储容量要大于顺序表的长度。)
typedef struct{
int *head; //声明了一个名为 head 的长度不确定的数组,也叫“动态数组”
int length; //记录表中存储数据元素的个数
int size; //记录顺序表分配的存储容量
}tabel;
#define Size 5
tabel initTable()
{
tabel t;
t.head = (int *)malloc(Size*sizeof(int));
if(!t.head)
{
printf("初始化失败");
exit(0);
}
t.length = 0;
t.size = Size;
return t;
}
//插入函数,其中place 为插入到顺序表的位置 ,data 为插入的元素
tabel addTabel(tabel t,int place,int data)
{
//判断插入是否有问题
if(place>t.length+1 ||place <0 )
{
printf("插入的位置有问题\n");
return t;
}
//做插入操作时,首先需要看顺序表是否有多余的存储空间提供给插入的元素,如果没有,需要申请
if(t.length >= t.size)
{
t.head = (int *)realloc(t.head,(t.size+1)*sizeof(int));
if(t.head == NULL)
{
printf("存储分配失败\n");
return t;
}
t.size++;
}
//插入操作,需要将从插入位置开始的后续元素,逐个后移
for(int i=t.length-1;i>=place-1;i--)
{
t.head[i+1] = t.head[i];
}
//后移完成后,直接将所需插入元素,添加到顺序表的相应位置
t.head[place-1] = data;
t.length++;
return t;
}
// 顺序表删除元素
tabel delTabel(tabel t,int place)
{
//1.判断删除的元素的位置是否正确
if(place>t.length || place<0)
{
printf("被删除的元素的位置有误!\n");
return t;
}
//2.执行删除操作
for(int i=place;i<t.length;i++)
{
t.head[i-1] = t.head[i];
}
t.length --;
return t;
}
//查找函数,其中,data 表示要查找的数据元素的值
//如果查找成功返回元素的位置
int findTabel(tabel t,int data)
{
for(int i=0;i<t.length;i++)
{
if(t.head[i] == data)
{
return i+1;
}
}
return -1;//如果查找失败,返回-1
}
// 顺序表更改元素的实现过程是:
// 1. 找到目标元素;
// 2. 直接修改该元素的值;
tabel changeTabel(tabel t,int data,int newdata)
{
int place;//定义需要修改元素的位置,先查找到元素
place = findTabel(t,data);
t.head[place-1] = newdata;//由于返回的是元素在顺序表中的位置,所以place-1 就是该元素在数组中的下标
return t;
}
void displayTable(tabel t)
{
for(int i=0;i<t.length;i++)
{
printf("%d ",t.head[i]);
}
printf("\n");
}
int main()
{
tabel t;
int i;
t = initTable();
//向顺序表中添加元素组
for(i=0;i<Size;i++)
{
t.head[i] = i+1;
t.length++;
}
printf("顺序表中存储的元素分别是:\n");
displayTable(t);
//向顺序表元素
printf("向顺序表中第3个位置插入元素6\n");
t = addTabel(t,3,6);
displayTable(t);
//向顺序表中删除元素
printf("删除第3个位置上的元素:\n");
t = delTabel(t,3);
displayTable(t);
//查找
printf("查找元素3的位置:%d\n",findTabel(t,3));
//更改元素
printf("将元素4更改为元素6\n");
t = changeTabel(t,4,6);
displayTable(t);
//申请内存要释放掉,不然会造成内存泄露
free(t.head);
return 0;
}