数据结构——顺序表

news/2024/4/27 20:46:41

大家好,我是小锋,今天我们进入顺序表的学习

线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使
用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,
线性表在物理上存储时,通常以数组和链式结构的形式存储

这里我们给大家讲解的时顺序表,后面还会给大家带来链表

顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存
储。在数组上完成数据的增删查改。
静态顺序表:使用定长数组存储元素

我们可以看出这种定长的数组能存储多少数据一开始就已经规定好了,那我们可不可以弄一个动态的表,如果空间满了我们可以动态开辟空间?

动态顺序表:使用动态开辟的数组存储

我们主要讲解动态开辟的顺序表的操作

我们先来创建一个结构体变量,并将它初始化

为了方便测试我们可分装一个函数ddps1来测试

#define N 10
typedef int CMMlet;//动态顺序表
typedef struct JTadd {CMMlet* dest;//指向动态开辟的数组CMMlet SZ;//有效数据个数CMMlet rl;//动态开辟的数组的容量
}dtkaip;//初始化
void ChuShiHua(dtkaip* pdd) {pdd->dest = (CMMlet)malloc(sizeof(CMMlet) * N);if (pdd->dest == NULL) {perror("malloc");return;}memset(pdd->dest, 0, sizeof(CMMlet) * N);pdd->SZ = 0;pdd->rl = 0;}
//这是一个测试函数
void ddps1() {dtkaip pdd;//初始化ChuShiHua(&pdd);
}
int main() {ddps1();return 0;
}

头文件,大家就自己包含下了。

为了方便观察,我们再实现一下打印顺序表

//打印顺序表
void dysunxu(dtkaip* pdd) {int n = 0;for (n = 0; n < pdd->SZ; n++) {printf("%d ", pdd->dest[n]);}
}

尾插数据和尾删数据

首先我们来讲讲尾插数据

首先我们应该判断顺序表的容量,再进行插入数据

//尾插数据
void destadd(dtkaip* pdd,CMMlet a) {if (pdd->SZ == pdd->rl) {//扩容kuorong(pdd);}pdd->dest[pdd->SZ] = a;pdd->SZ++;}

这是扩容函数

//扩容
void kuorong(dtkaip* ps) {assert(ps != NULL);//断言CMMlet * arr = (CMMlet)realloc(ps->dest,(ps->rl * 2)*sizeof(CMMlet));//扩容if (arr == NULL) {printf("%s", strerror(errno));return;}ps->dest = arr;ps->rl *= 2;
}

接下来我们来讲尾删数据,其实很简单,我们只需要把SZ--就行了,但是要注意断言SZ要大于0,

实现如下,

//尾删数据
void destmee(dtkaip* pdd) {assert(pdd->SZ >= 0);pdd->SZ--;}

大家看是不是实现了删除效果?

我们还可以看看当删除过多会怎么样?

我们断言是比较暴力的解决方法,我们还有温柔的解决方法

//尾删数据
void destmee(dtkaip* pdd) {//assert(pdd->SZ >= 0);//暴力断言if (pdd->SZ == 0) {return;}pdd->SZ--;}

这是比较温柔的解决方法

头插数据和头删数据

我们这里创建一个ddps2来来验证

我们先来实现头插数据

首先我们肯定要判断容量够不够,然后再头部插入数据我们应该先将其他数据挪动位置向后挪一位再将插入的数据放进去

//头插数据
void TCshuju(dtkaip* pdd, CMMlet a) {if (pdd->SZ == pdd->rl) {//扩容kuorong(pdd);}CMMlet n = 0;for (n = pdd->SZ; n >0; n--) {pdd->dest[n] = pdd->dest[n - 1];}pdd->dest[0] = a;pdd->SZ++;
}

头删数据

我们这里采用的是覆盖删除直接将后一个元素向前覆盖,还要注意断言防止删除多了

//头删数据
void TSshuju(dtkaip* pdd) {assert(pdd->SZ >= 0);//断言CMMlet n = 0;for (n = 2; n < pdd->SZ; n++) {pdd->dest[n] = pdd->dest[n - 1];}pdd->SZ--;
}

顺序表在pos的位置插入x

与前两给插入类似我们先判断容量够不够再pos的位置上及后面的元素向后移动一个

这里我们要注意的是我们不能在没有数据的地方插入。(所以这里要断言一下)

我们用ddps3来测试

//顺序表在pos位置上插入数据n
void POScharu(dtkaip *pdd,int a,CMMlet n){assert(pdd->SZ >= a);if (pdd->rl == pdd->SZ) {//扩容kuorong(pdd);}for (int i=pdd->SZ; i>=a; i--) {pdd->dest[i] = pdd->dest[i - 1];}pdd->dest[a] = n;pdd->SZ++;
}

顺序表在pos位置删除数据

这里与前面一样也是覆盖删除,要注意的是保证pos的位置比SZ小或者相等,还要保证删除的次数不能大于SZ

//顺序表pos位置删除数据
void POSshanchu(dtkaip* pdd, int a) {assert(pdd->SZ >= a && pdd->SZ >= 0);for (int i = a; i < pdd->SZ-1; i++) {pdd->dest[i] = pdd->dest[i + 1];}pdd->SZ--;
}

顺序表查找

这里很简单我们直接遍历顺序表查找就行了

如果找到了我们返回下标如果没找到我们返回-1.

//查找顺序表
int CZsunxu(dtkaip* pdd,CMMlet a) {for (int i = 0; i < pdd->SZ; i++) {if (pdd->dest[i] == a) {return i;}}return -1;
}

销毁顺序表

当我们退出顺序表是我们动态开辟出来的空间应该销毁掉。

//销毁顺序表
void XHsunxu(dtkaip* pdd) {free(pdd->dest);pdd->dest = NULL;pdd->rl = 0;pdd->SZ = 0;
}

大家有没有发现顺序表的操作与我们写过的通讯录特别相似,因为通讯录的底层逻辑就是顺序表

# define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
# include<string.h>
# include<assert.h>
# include<stdlib.h>#define N 2
typedef int CMMlet;//动态顺序表
typedef struct JTadd {CMMlet* dest;//指向动态开辟的数组CMMlet SZ;//有效数据个数CMMlet rl;//动态开辟的数组的容量
}dtkaip;
//扩容
void kuorong(dtkaip* ps) {assert(ps != NULL);//断言CMMlet * arr = (CMMlet)realloc(ps->dest,(ps->rl * 2)*sizeof(CMMlet));//扩容if (arr == NULL) {printf("%s", strerror(errno));return;}//printf("扩容成功\n");ps->dest = arr;ps->rl *= 2;
}//初始化
void ChuShiHua(dtkaip* pdd) {pdd->dest = (CMMlet)malloc(sizeof(CMMlet) * N);if (pdd->dest == NULL) {printf("%s", strerror(errno));return;}memset(pdd->dest, 0, sizeof(CMMlet) * N);pdd->SZ = 0;pdd->rl = N;}
//打印顺序表
void dysunxu(dtkaip* pdd) {int n = 0;for (n = 0; n < pdd->SZ; n++) {printf("%d ", pdd->dest[n]);}printf("\n");
}
//头插数据
void TCshuju(dtkaip* pdd, CMMlet a) {if (pdd->SZ == pdd->rl) {//扩容kuorong(pdd);}CMMlet n = 0;for (n = pdd->SZ; n >0; n--) {pdd->dest[n] = pdd->dest[n - 1];}pdd->dest[0] = a;pdd->SZ++;
}//头删数据
void TSshuju(dtkaip* pdd) {assert(pdd->SZ >= 0);//断言CMMlet n = 0;for (n = 2; n < pdd->SZ; n++) {pdd->dest[n] = pdd->dest[n - 1];}pdd->SZ--;
}//尾插数据
void destadd(dtkaip* pdd,CMMlet a) {if (pdd->SZ == pdd->rl) {//扩容kuorong(pdd);}pdd->dest[pdd->SZ] = a;pdd->SZ++;}
//尾删数据
void destmee(dtkaip* pdd) {//assert(pdd->SZ >= 0);//暴力断言if (pdd->SZ == 0) {return;}pdd->SZ--;}
//顺序表在pos位置上插入数据n
void POScharu(dtkaip *pdd,int a,CMMlet n){assert(pdd->SZ >= a);if (pdd->rl == pdd->SZ) {//扩容kuorong(pdd);}for (int i=pdd->SZ; i>=a; i--) {pdd->dest[i] = pdd->dest[i - 1];}pdd->dest[a] = n;pdd->SZ++;
}//顺序表pos位置删除数据
void POSshanchu(dtkaip* pdd, int a) {assert(pdd->SZ >= a && pdd->SZ >= 0);for (int i = a; i < pdd->SZ-1; i++) {pdd->dest[i] = pdd->dest[i + 1];}pdd->SZ--;
}
//查找顺序表
int CZsunxu(dtkaip* pdd,CMMlet a) {for (int i = 0; i < pdd->SZ; i++) {if (pdd->dest[i] == a) {return i;}}return -1;
}//销毁顺序表
void XHsunxu(dtkaip* pdd) {free(pdd->dest);pdd->dest = NULL;pdd->rl = 0;pdd->SZ = 0;
}//这是一个测试函数
//void ddps1() {
//	dtkaip pdd;
//	//初始化
//	ChuShiHua(&pdd);
//	destadd(&pdd, 1);
//	destadd(&pdd, 2);
//	destadd(&pdd, 3);
//
//	dysunxu(&pdd);
//
//	destmee(&pdd);
//	destmee(&pdd);
//}//这是测试函数
//void ddps2() {
//	dtkaip pdd;
//	//初始化
//	ChuShiHua(&pdd);
//	destadd(&pdd, 1);
//	destadd(&pdd, 2);
//	destadd(&pdd, 3);
//	//头插数据
//	TCshuju(&pdd, 0);
//	//头删数据
//	//TSshuju(&pdd);
//	//TSshuju(&pdd);
//	//TSshuju(&pdd);
//	//打印
//	dysunxu(&pdd);
//}void ddps3() {dtkaip pdd;//初始化ChuShiHua(&pdd);//头插数据destadd(&pdd, 1);destadd(&pdd, 2);destadd(&pdd, 3);int n=CZsunxu(&pdd, 2);}int main() {//ddps1();ddps3();return 0;
}

本期所有的代码全都在这里大家可以自己动手测试一下。

 以上就是全部内容了,如果有错误或者不足的地方欢迎大家给予建议。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/11076.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

基于Python实现矩阵数据的按列求和计算

下午在功能开发的时候遇上一个小功能点的实现过程中需要对矩阵数据按列求和计算&#xff0c;输出一维的列表数据&#xff0c;有点像是神经网络模型里面的Flatten一样&#xff0c;这里实现是很简单的&#xff0c;在实现的时候我突然涌现出来了一个有趣的想法&#xff0c;除了我自…

【新手小白教程】2024最新:如何轻松订阅Patreon及其支付、充值全攻略

前言 什么是Patreon Patreon是一个极具创新性的在线平台&#xff0c;它为内容创作者提供了一个独特的机会&#xff0c;使他们能够直接通过订阅服务模式从粉丝那里获得资金支持或打赏。 这个平台吸引了各种类型的创作者&#xff0c;包括艺术家、音乐家、作家、视频制作人等&…

微服务demo(二)nacos服务注册

一、服务注册 1、pom&#xff1a; 移步spring官网https://spring.io&#xff0c;查看集成Nacos所需依赖 找到对应版本点击进入查看集成说明 然后再里面找到集成配置样例&#xff0c;这里只截一张&#xff0c;其他集成内容继续向下找 2、配置文件 &#xff08;1&#xff09;有…

python初级第一次作业

一、 dayint(input("enter today day")) fdayint(input("enter num of day since today")) c((fday%7)day)%7 if c0:print("sunday") elif c1:print("monday") elif c2:print("tuesday") elif c3:print("wendnsday&quo…

景联文科技上新高质量大模型训练数据!

在过去的一年中&#xff0c;人工智能领域呈现出了风起云涌的态势&#xff0c;其中模型架构、训练数据、多模态技术、超长上下文处理以及智能体发展等方面均取得了突飞猛进的发展。 在3月24日举办的2024全球开发者先锋大会的大模型前沿论坛上&#xff0c;上海人工智能实验室的领…

链动2+1模式 完全合法合规 不存在传销问题!!

在商业经营中&#xff0c;营销策略的巧妙运用对于提升产品销量和扩大品牌影响力至关重要。然而&#xff0c;企业在制定和执行营销策略时&#xff0c;必须严格遵循法律法规&#xff0c;以免陷入法律风险。本文将着重探讨链动21模式的法律要素&#xff0c;以论证其合规性。 一、链…