顺序表的存储结构(动态)

顺序表的存储结构(动态)
在建立顺序表时,除了预先申请内存空间,还需要实时记录顺序表的长度和顺序表本身申请的内存大小,便于后期对顺序表中的数据元素进行调取。

所以,要自定义顺序表的结构:
在这里插入图片描述
顺序表的创建
顺序表的建立,也就是顺序表进行初始化,在预先申请内存空间的同时,给变量size和length赋初值:
在这里插入图片描述
顺序表查找元素
在数组中查找某个数据元素时,可以采取多种查找算法,例如二分查找、插值查找、斐波那契查找算法等。

具体的查找算法以及各自的时间复杂度后续章节会介绍。
根据顺序表中存储的数据的特点,选择合适的算法。这里,采用顺序查找算法(普通的遍历算法)。

实现代码:

//查找函数,其中,elem表示要查找的数据元素的值
在这里插入图片描述
顺序表中更改元素
顺序表中更改数据元素,最简单直接的方式就是:调用查找算法找到该数据元素的位置,直接在该位置上更改。

实现代码:
//更改函数,其中,elem为要更改的元素,newElem为新的数据元素
在这里插入图片描述
顺序表插入元素
插入数据元素,无非三种情况:
在表头插入
在表的中间某个位置插入
直接尾随顺序表,作为表的最后一个元素

无论在顺序表的什么位置插入数据元素,解决办法都是:找到要插入的位置,将后续数据元素整体向后移动一个位置,最后直接在腾出来的位置上插入数据元素。

实现代码:
在这里插入图片描述
注意:在此程序中,当数组存储空间不足时,使用realloc函数每次额外多申请 1 个int型的存储空间,这么做还不是最优。最好的办法就是每次发现空间不够时,多申请几个内存空间,这么做的好处是:在后续做插入操作过程中不需要每次都运行realloc函数,提高了程序的运行效率。

顺序表删除元素
在数组中删除元素时,只需将该元素所在位置后的所有数据元素整体前移 1 个位置即可。
前移的过程中被删除元素被后一个元素覆盖掉,间接实现了删除操作。
实现代码:
在这里插入图片描述
完整的程序
#include <stdio.h>
#include <stdlib.h>
#define Size 4
typedef struct Table{
int * head;
int length;
int size;
}table;
table initTable(){
table t;
t.head=(int*)malloc(Size*sizeof(int));
if (!t.head)
{
printf(“初始化失败”);
exit(0);
}
t.length=0;
t.size=Size;
return t;
}
table addTable(table t,int elem,int add)
{
if (add>t.length+1||add<1) {
printf(“插入位置有问题”);
return t;
}
if (t.length>=t.size) {
t.head=(int *)realloc(t.head, (t.size+1)*sizeof(int));
if (!t.head) {
printf(“存储分配失败”);
}
t.size+=1;
}
for (int i=t.length-1; i>=add-1; i–) {
t.head[i+1]=t.head[i];
}
t.head[add-1]=elem;
t.length++;
return t;
}
table delTable(table t,int add){
if (add>t.length || add<1) {
printf(“被删除元素的位置有误”);
exit(0);
}
for (int i=add; i<t.length; i++) {
t.head[i-1]=t.head[i];
}
t.length–;
return t;
}
int selectTable(table t,int elem){
for (int i=0; i<t.length; i++) {
if (t.head[i]==elem) {
return i+1;
}
}
return -1;
}
table amendTable(table t,int elem,int newElem){
int add=selectTable(t, elem);
t.head[add-1]=newElem;
return t;
}
void displayTable(table t){
for (int i=0;i<t.length;i++) {
printf("%d",t.head[i]);
}
printf("\n");
}
int main(){
table t1=initTable();
for (int i=1; i<=Size; i++) {
t1.head[i-1]=i;
t1.length++;
}
printf(“原顺序表:\n”);
displayTable(t1);
printf(“删除元素1:\n”);
t1=delTable(t1, 1);
displayTable(t1);
printf(“在第2的位置插入元素5:\n”);
t1=addTable(t1, 5, 2);
displayTable(t1);
printf(“查找元素3的位置:\n”);
int add=selectTable(t1, 3);
printf("%d\n",add);
printf(“将元素3改为6:\n”);
t1=amendTable(t1, 3, 6);
displayTable(t1);
return 0;
}
输出结果:
原顺序表:
1234
删除元素1:
234
在第2的位置插入元素5:
2534
查找元素3的位置:
3
将元素3改为6:
2564
顺序表的优缺点
顺序表实现的基础,完全借用了数组这一数据类型,优点是在对数据进行遍历时,数据在连续的物理空间中存放,查找的速度比较快。

但是由于数组本身的限制,在向顺序表中新增或者删除数据元素时,如果被操作位置后续有很多数据元素,后续所有的数据元素都需要前移,最后虽然实现了功能,但是程序总体效率不高。

猜你喜欢

转载自blog.csdn.net/weixin_44545549/article/details/86528613