①前言

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数据结构线性表:实现顺序表的增删改查&完整篇的更多相关文章

  1. 第二百七十七节,MySQL数据库-数据表、以及列的增删改查

    MySQL数据库-数据表.以及列的增删改查 1.创建一个表 CREATE(创建) TABLE(表) ENGINE(引擎) ENGINE=INNODB(引擎)还有很多类引擎,这里只是简单的提一下INNO ...

  2. Django中ORM表的创建以及基本增删改查

    Django作为重量级的Python web框架,在做项目时肯定少不了与数据库打交道,编程人员对数据库的语法简单的还行,但过多的数据库语句不是编程人员的重点对象.因此用ORM来操作数据库相当快捷.今天 ...

  3. IDEA对数据库、表、记录的(增删改查可视化操作)、数据库安全性问题的演示

    对数据库的增删改查 新增数据库 修改数据库 删除数据库 对表的增删改查 新增表 修改表 删除表 对记录的增删改查 数据库安全性问题的演示 演示脏读 ​ 一个事物里面读到了另外一个事物没有提交的数据: ...

  4. MySQL数据库-数据表、以及列的增删改查

    1.创建一个表 CREATE(创建) TABLE(表) ENGINE(引擎) ENGINE=INNODB(引擎)还有很多类引擎,这里只是简单的提一下INNODB引擎,INNODB引擎支持事务(回滚), ...

  5. iptables详解(2)表中规则管理(增删改查)

    我们定义了四张表:raw表.mangle表.nat表.filter表,不同的表有不同的功能 filter表用来过滤,允许哪些ip.端口访问,禁止哪些ip.端口访问,表中会有很多链 ①禁止ip地址访问我 ...

  6. 【hbase】——Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  7. (转)Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  8. Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  9. 4.SSM整合_多表_多对多的增删改查

    多对多关系,课程和学生 接口 public interface CourseMapper { /** * 获取所有课程 * @return * @throws Exception */ public ...

  10. 3.SSM整合_多表_一对多的增删改查

    1.配置文件跟上一章一样,这里就不多写了,主要是Mapper映射文件,一对多反过来就是多对一 一 接口 public interface CategoryMapper { public void ad ...

随机推荐

  1. Matplotlib绘图设置---坐标轴上下限/标题设置

    坐标轴上下限设置 plt.plot(x, np.sin(x)) #设置坐标轴上下限 plt.xlim(-1, 11) plt.ylim(-1.5, 1.5) plt.plot(x, np.sin(x) ...

  2. vue3 快速入门系列 —— vue3 路由

    vue3 快速入门系列 - vue3 路由 在vue3 基础上加入路由. vue3 需要使用 vue-router V4,相对于 v3,大部分的 Vue Router API 都没有变化. Tip:不 ...

  3. js获取select标签的 value 和 text

    <select name="" id="test"> <option value="a1">yi</optio ...

  4. 攻防世界Reverse三星题 zorropub

    题目 分析过程 丢到PE里面,无壳,64bit 丢到IDA里面,查看mian函数 1 int __fastcall main(int a1, char **a2, char **a3) 2 { 3 s ...

  5. HDD杭州站·HarmonyOS技术专家分享HUAWEI DevEco Studio特色功能

    原文:https://mp.weixin.qq.com/s/87diJ1RePffgaFyd1VLijQ,点击链接查看更多技术内容. 7月15日,HUAWEI Developer Day(简称HDD) ...

  6. 如何使用 Grafana 监控文件系统状态

    当 JuiceFS 文件系统部署完成并投入生产环境,接下来就需要着手解决一个非常重要的问题 -- 如何实时监控它的运行状态?毕竟,它可能正在为关键的业务应用或容器工作负载提供持久化存储支持,任何小小的 ...

  7. 因果推断review

    什么是因果推断? 因果推断(Causal Inference):就是预估对某个对象/群体/人 等 做不做某种干预后产生的结果. 常说'关系不代表因果'. 比如,一项研究表面,吃早餐的女孩比不吃早餐的女 ...

  8. CentOS GNOME桌面下安装截图工具gnome-screenshot

    CentOS GNOME桌面下安装截图工具gnome-screenshot 1.光盘安装 (1).把镜像光盘放进电脑 (2).切换到 Packages (3).[root@localhost Pack ...

  9. 了解redis的单线程模型工作原理?一篇文章就够了

    1.首先redis是单线程的,为什么redis会是单线程的呢?从redis的性能上进行考虑,单线程避免了上下文频繁切换问题,效率高:从redis的内部结构设计原理进行考虑,redis是基于Reacto ...

  10. 力扣613(MySQL)-直线上的最近距离(简单)

    题目: 表 point 保存了一些点在 x 轴上的坐标,这些坐标都是整数. 写一个查询语句,找到这些点中最近两个点之间的距离. 最近距离显然是 '1' ,是点 '-1' 和 '0' 之间的距离.所以输 ...