C数据结构线性表:实现顺序表的增删改查&完整篇
文章目录
①前言
1:大家在观看的过程中不必纠结我的变量名,都是用英语对应功能意思,应该都是比较好理解。
2:就是我的顺序表是全局变量,你完全可以在main函数里面进行定义,在本代码程序中,运行结果没有任何区别,因为我的函数都是考虑到大家的定义变量位置不同,所以每一个函数我都带了顺序表的参数。
3:删除功能的部分有两个函数,one第一个是删除在顺序表中最先找到与你要删除的相同的一个元素,two第二个函数是把顺序表中找到所有的与你要删除的相同的元素进行删除。其实就是第一个函数是不管后面有没有多个重复与你要删除的元素。
顺序表结构体的定义
结构体中lenth表示整一个顺序表的长度,不是从0开始的长度,因为这个以后可能会给自己或者用户看的。
typedef struct _Link{
int *elem;
int lenth;//顺序表长度
}Link;
②初始化顺序表
MAX_LEN表示为顺序表能够存储的最大空间长度
使用动态分配内存空间,我认为这样方便我们日后需要的时候去修改,只要修改MAX_LEN就可以改变空间大小
!如果你觉得宏定义还不够灵活,你想要自己录入空间,那你就直接把宏定义改成全局变量!
void Init_Link(Link *L)
{
int i;
L->elem = (int*)malloc(MAX_LEN*sizeof(int));
L->lenth = MAX_LEN/2; //假设现需存放最大空间的一半的顺序表长度
for(i = 0; i < L->lenth; i++) L->elem[i] = i+1;//初始化内容
}
③插入新的元素
插入的时候需要特别注意的几点
1:当你要删除的元素为最后一个的时候直接把顺序表的长度减一
2:在使用元素下标的时候必须要特别的小心谨慎,一不小心就会导致下标越界或者运行的结果不尽人意。
注:第一个参数是你要插入在顺序表中哪个一个下标位置,第二个参数就是要操作的顺序表,第三个是你要插入的元素。
void Insert_Link(int putindex, Link *L, int putelem)
{
int i;
if(putindex > L->lenth+1 || putindex <= 0)
{
PF(不能插入该位置!);
return;
}
if(L->lenth >= MAX_LEN)
{
PF(空间已满,插入失败!);//判断是否还有空间能插入
return;
}
if(putindex == L->lenth+1)//若想要插入的位置为尾部,那直接把这个元素插进最后就行
{
L->elem[L->lenth] = putelem;
L->lenth++;//长度加一
return;
}
else
{
for(i = L->lenth; i > putindex-1; i--)
{
L->elem[i] = L->elem[i-1];//putindex这个位置和它之后的元素全部往后移动一个空间
}
L->elem[putindex-1] = putelem;//插入元素
L->lenth++;//长度加一
}
}
④删除元素
两个函数的区别我在前言的时候说过了,还要提醒的是切记切记用元素下标的时候一定要谨慎谨慎再谨慎。
第一个删除元素功能实现
第一个是在顺序表中第一个找到你要删除的那个元素进行删除,不管后面是否还重复出现要删除的元素。这个比较简单,就是找到删除元素后直接把该元素位置和后面元素都往前移动一步,最后再把元素的长度减一。
void Delete_Link_one(int index, Link *L)
{
int i;
if(index > L->lenth || index <= 0)
{
PF(该位置不能删除!);
return;
}
else
{
for(i = index-1; i < L->lenth-1; i++)//L->lenth减一是因为下面我要i+1进行赋值,不然会导致越界
{
L->elem[i] = L->elem[i+1];
}
L->lenth--;//长度减一
}
}
第二个删除元素功能实现
第二个功能就相对于第一个就上升了一点点难度,其实就是下标会比较让人觉得烦躁,只要你捋清楚了下标是对应哪个,能够准确无误的让数组按照你的想法进行就完全能理解到位了。
对代码下面中**i- -**的说明(第二个删除函数)
因为你进来if语句的时候是为了删除该下标的元素,删除完成后该下标已经不是你要删除的元素了,而是后面赋值上来的新的元素。因为当你跳出这个if语句之后下面有一个i++,所以为了使其下标回到刚进来 i 的那个位置,先进行i- -出去之后再i++,毕竟你还要继续进行判断该位置下新的赋值过来的元素是否和你要删除元素一样,这函数就是要删除掉和你要删除元素一样的所有重复元素
void Delete_Link_two(int D_elem, Link *L)
{
int i = 0, j;
while(1)
{
if(i == L->lenth-1 && L->elem[i] == D_elem)//当需要删除的元素是最后一个的时候直接把长度减一就好
{
L->lenth--;
}
if(L->elem[i] == D_elem && i < L->lenth-1)
{
for(j = i; j < L->lenth-1; j++)//L->lenth-1是因为下面我要对i+1进行赋值,不然会导致越界
{
L->elem[j] = L->elem[j+1];
}
L->lenth--;//长度减一
i--;//在文章中有特别对该部分进行详细讲解原因
}
i++;
if(i > L->lenth) break;
}
}
⑤查找某一个元素,并打印其下标
查找元素就基本没什么好说的了,属于比较容易理解的部分。原理就是当你在顺序表中找到与你查找的那个元素的时候,直接返回他的下标就行,这个函数有个局限性,就是只能在顺序表中找到第一个相同的那个返回其下标,这个找到这个元素后,顺序表往后的就不找了。
void Find_Link_elem(int elem, int *index, Link *L)
{
int i;
for(i = 0; i < L->lenth-1; i++)
{
if(elem == L->elem[i])
{
*index = i+1;
return;
}
}
if(i == L->lenth-1) PF(不存在该元素!\n);
}
⑥清空顺序表
有时候我们对顺序表中的内容没有作用了的时候,这时候就需要把顺序表中的内容清空,再存储其他内容信息。清空操作也很简单,就不继续赘述了。
void Clear_Link(Link *L)
{
int i;
for(i = 0; i < L->lenth; i++) L->elem[i] = 0;
L->lenth = 0;//长度记为0
}
⑦销毁顺序表
因为我们的顺序表是通过动态分配出来的,我们不需要的时候要及时的销毁掉,***在程序结束前养成习惯,需要对分配在栈上的空间释放掉。***这个也比较简单,也不赘述了。
void Destroy_Link(Link *L)
{
free(L->elem);//直接释放顺序表开辟的空间
L = NULL;//指针直接指向空,完全把顺序表销毁掉
}
总:附上源代码
源代码中有一些是我自己加的函数,也不难理解,都是为了测试运行结果而打包成函数的。
打印PF那个也不用纠结,我只是用宏定义换了一个我习惯用的方式来打印而已。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#define MAX_LEN 10
#define PF(format, ...) printf(#format, ##__VA_ARGS__)
/*
线性表的基本操作
*/
typedef struct _Link{
int *elem;
int lenth;//顺序表长度
}Link;
Link L;//在本代码程序中,顺序表作为全局变量或者在main函数里面定义没有区别
bool IsEmpty(Link);//判断顺序表是否为空
void Init_Link(Link *);//初始化顺序表
void Destroy_Link(Link *);//销毁顺序表
void Clear_Link(Link *);//清空顺序表内容 即全部赋值为某一个特殊标志,如int数组全部赋值为 0
void Insert_Link(int putindex, Link *, int putelem);//在第一个参数putindex下标位置下,顺序表插入新元素 putelem
void P_Link(Link *);//打印顺序表内容
void Delete_Link_one(int index, Link*);//删除下标为index的元素
void Delete_Link_two(int D_elem, Link*);//删除传进的这一个元素,若顺序表有 重复元素则相同的也全部删除
void Find_Link_elem(int, int *index, Link *);//寻找一个元素 ,找到第一个与他相同的元素,并返回下标给 index
int main(void)
{
// Link L;
int index = -1;//找到想要的元素后,用来接收该元素在顺序表中的下标
Init_Link(&L);//初始化顺序表
P_Link(&L);
PF(************************************************\n);
Insert_Link(1, &L, 4);
if(IsEmpty(L)) P_Link(&L);
PF(************************************************\n);
Delete_Link_one(4, &L);
if(IsEmpty(L)) P_Link(&L);
PF(************************************************\n);
Delete_Link_two(4, &L);
if(IsEmpty(L)) P_Link(&L);
Find_Link_elem(5, &index, &L);
if(index != -1) PF(元素下标为:%d\n, index);
return 0;
}
bool IsEmpty(Link L)
{
if(L.lenth == 0)
{
PF(顺序表为空(NULL));
return false;
}
else if(L.lenth > 0)
{
return true;
}
}
void Init_Link(Link *L)
{
int i;
L->elem = (int*)malloc(MAX_LEN*sizeof(int));
L->lenth = MAX_LEN/2; //现在存放顺序表长度
for(i = 0; i < L->lenth; i++) L->elem[i] = i+1;//初始化内容
}
void Destroy_Link(Link *L)
{
free(L->elem);//直接释放顺序表开辟的空间
L = NULL;//指针直接指向空,完全把顺序表销毁掉
}
void Clear_Link(Link *L)
{
int i;
for(i = 0; i < L->lenth; i++) L->elem[i] = 0;
L->lenth = 0;//长度记为0
}
void Insert_Link(int putindex, Link *L, int putelem)
{
int i;
if(putindex > L->lenth+1 || putindex <= 0)
{
PF(不能插入该位置!);
return;
}
if(L->lenth >= MAX_LEN)
{
PF(空间已满,插入失败!);//判断是否还有空间能插入
return;
}
if(putindex == L->lenth+1)//若想要插入的位置为尾部,那直接把这个元素插进最后就行
{
L->elem[L->lenth] = putelem;
L->lenth++;//长度加一
return;
}
else
{
for(i = L->lenth; i > putindex-1; i--)
{
L->elem[i] = L->elem[i-1];//putindex这个位置和它之后的元素全部往后移动一个空间
}
L->elem[putindex-1] = putelem;//插入元素
L->lenth++;//长度加一
}
}
void P_Link(Link *L)
{
int i;
for(i = 0; i < L->lenth; i++)
{
PF(%d\t, L->elem[i]);
}
putchar('\n');
}
void Delete_Link_one(int index, Link *L)
{
int i;
if(index > L->lenth || index <= 0)
{
PF(该位置不能删除!);
return;
}
else
{
for(i = index-1; i < L->lenth-1; i++)//L->lenth减一是因为下面我要i+1进行赋值,不然会导致越界
{
L->elem[i] = L->elem[i+1];
}
L->lenth--;//长度减一
}
}
void Delete_Link_two(int D_elem, Link *L)
{
int i = 0, j;
while(1)
{
if(i == L->lenth-1 && L->elem[i] == D_elem)//当需要删除的元素是最后一个的时候直接把长度减一就好
{
L->lenth--;
}
if(L->elem[i] == D_elem && i < L->lenth-1)
{
for(j = i; j < L->lenth-1; j++)//L->lenth-1是因为下面我要对i+1进行赋值,不然会导致越界
{
L->elem[j] = L->elem[j+1];
}
L->lenth--;//长度减一
i--;
}
i++;
if(i > L->lenth) break;
}
}
void Find_Link_elem(int elem, int *index, Link *L)
{
int i;
for(i = 0; i < L->lenth-1; i++)
{
if(elem == L->elem[i])
{
*index = i+1;
return;
}
}
if(i == L->lenth-1) PF(不存在该元素!\n);
}
C数据结构线性表:实现顺序表的增删改查&完整篇的更多相关文章
- 第二百七十七节,MySQL数据库-数据表、以及列的增删改查
MySQL数据库-数据表.以及列的增删改查 1.创建一个表 CREATE(创建) TABLE(表) ENGINE(引擎) ENGINE=INNODB(引擎)还有很多类引擎,这里只是简单的提一下INNO ...
- Django中ORM表的创建以及基本增删改查
Django作为重量级的Python web框架,在做项目时肯定少不了与数据库打交道,编程人员对数据库的语法简单的还行,但过多的数据库语句不是编程人员的重点对象.因此用ORM来操作数据库相当快捷.今天 ...
- IDEA对数据库、表、记录的(增删改查可视化操作)、数据库安全性问题的演示
对数据库的增删改查 新增数据库 修改数据库 删除数据库 对表的增删改查 新增表 修改表 删除表 对记录的增删改查 数据库安全性问题的演示 演示脏读 一个事物里面读到了另外一个事物没有提交的数据: ...
- MySQL数据库-数据表、以及列的增删改查
1.创建一个表 CREATE(创建) TABLE(表) ENGINE(引擎) ENGINE=INNODB(引擎)还有很多类引擎,这里只是简单的提一下INNODB引擎,INNODB引擎支持事务(回滚), ...
- iptables详解(2)表中规则管理(增删改查)
我们定义了四张表:raw表.mangle表.nat表.filter表,不同的表有不同的功能 filter表用来过滤,允许哪些ip.端口访问,禁止哪些ip.端口访问,表中会有很多链 ①禁止ip地址访问我 ...
- 【hbase】——Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询
1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...
- (转)Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询
1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...
- Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询
1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...
- 4.SSM整合_多表_多对多的增删改查
多对多关系,课程和学生 接口 public interface CourseMapper { /** * 获取所有课程 * @return * @throws Exception */ public ...
- 3.SSM整合_多表_一对多的增删改查
1.配置文件跟上一章一样,这里就不多写了,主要是Mapper映射文件,一对多反过来就是多对一 一 接口 public interface CategoryMapper { public void ad ...
随机推荐
- #min-max容斥,FWT#洛谷 3175 [HAOI2015]按位或
题目 分析 按位去看,最终的答案要求 \(E(\max S)\) 就是 \(S\) 出现的期望时间. 根据min-max容斥,\(E(\max S)=\sum_{T\subset S}(-1)^{|T ...
- 准备Python环境学习OpenCV的使用
安装venv模块,执行如下命令: sudo apt-get install python3-venv 创建venv环境,命名为images,执行如下命令: python3 -m venv images ...
- Python生成唯一ID----UUID
# UUID 生成唯一ID # uuid 是Python内置模块,主要有五种算法. import uuid # uuid1() 基于时间戳 a1 = uuid.uuid1() print('uuid1 ...
- ES6~ES9
ES6 1. let 1.1 let 变量声明及声明特性 let 用来声明变量,具有以下特性: 一.相较于 var ,let 变量不能重复声明 let a = 'a'; let a = 'a'; // ...
- node excel采集数据
前言 个人写过无数的脚本,但是一直没有整理,后续整理脚本. 需求: 生成一堆激活码. 业务: 需要拿到一个token, 然后调用某个api获取激活码. 正文 思路: 1.http请求 axios 2. ...
- Pytorch-均方差损失函数和交叉熵损失函数
均方差损失函数mse_loss()与交叉熵损失函数cross_entropy() 1.均方差损失函数mse_loss() 均方差损失函数是预测数据和原始数据对应点误差的平方和的均值. \[MSE=\f ...
- Django框架——图书管理系统、聚合查询、分组查询、F与Q查询
图书管理系统 1.表设计 先考虑普通字段再考虑外键字段 数据库迁移.测试数据录入 2.首页展示 3.书籍展示 4.书籍添加 5.书籍编辑 后端如何获取用户想要编辑的数据.前端如何展示出待编辑的数据 6 ...
- ModelScope初探:一行代码调用成熟AI模型
简介: 如何用一行代码调用成熟AI模型?试试ModelScope,让AI开发者解放生产力! ModelScope是阿里推出的下一代开源的模型即服务共享平台,为泛AI开发者提供灵活.易用.低成本的一站式 ...
- 好的 MySQL 兼容性可以做到什么程度? PolarDB-X 如何做生态兼容
简介: 2003 年淘宝网成立之后,业务飞速发展,其后台架构也进行了多次迭代.2009 年之前,淘宝网后台的数据库架构是经典的 IOE 组合.IOE 是指 IBM 的小型机. Oracle 的数据库加 ...
- CNCF 沙箱项目 OCM Placement 多集群调度指南
简介:在这篇文章中,将介绍 Placement 如何选择到所需的集群,Placement 可以提供的调度功能,以及一些场景下的最佳实践,使用者可以参考示例来编写符合自己要求的 Placement.其 ...