c语言数据结构与算法--简单实现线性表(顺序表+链表)的插入与删除

        老规矩,点赞+评论+收藏+关注!!!

目录

线性表

其特点是:

算法实现:

运行结果展示

链表

插入元素:

删除元素:

算法实现

运行结果

        线性表是由n个数据元素组成的有限序列,每个元素都有唯一的下标,下标从0开始递增。线性表的元素之间存在一对一的线性关系,即除首元素外,每个元素有且只有一个前驱元素,除尾元素外,每个元素有且只有一个后继元素。线性表可以通过顺序存储或链式存储来实现。线性表的基本操作包括初始化、创建、增加、删除和查找等。

        顺序表和链表是线性表的两种实现方式,都是用来存储逻辑关系为“一对一”的数据。它们的相同点是:都是线性表结构;元素逻辑存储上是连续的;每个元素都有唯一的前驱和唯一的后继。它们的不同点是:底层存储空间不一样,顺序表底层存储空间是连续的,而链表则是不连续的;插入和删除方式不同,顺序表任意位置进行插入和删除操作,需要搬运大量的元素,效率低,时间复杂度为O(N)。顺序表集中存储数据,适合访问、遍历数据,在数据量确定时空间利用率高;链表通过指针链接数据,适合插入、删除数据,在数据量不确定时空间利用率高。

线性表

线性表的顺序表示是指用一组地址连续的存储单元依次存储线性表的数据元素。

其特点是:

1.第 i 个元素 a i 的存储位置可以用公式计 LOC(a i) = LOC(a1)+(i-1)*L

其中 LOC(a1)第一个元素a1 的存储位置,L 每个元素需占的存储单元

2.表中相邻的元素 a i a i+1赋以相邻的存 储位置 LOC(a i)和 LOC(a i+1)

3.是一种随机存储结构:只要知道线性表的 起始位置就可随机存取线性表中的任一元素。

        当我们要在线性表的顺序存储结构上的第 i 个位置上插入一个元素时,必须先将 线性表第 i 个元素之后的所有元素依次后移一个位置,以便腾空一个位置,再把新元素插入到该位置。若要删除第 i 个元素时,也必须把第 i 个元素之后的所有元素前 移一个位置。

算法实现:

1、引入头文件、定义结构体

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INIT_SIZE 100  //初始分配量
#define INCRE_SIZE 10  //分配增量typedef struct {int *pList;int length;int listSize;
}SqList;

2、创建顺序表

//顺序表的创建
void initial(SqList &L) {  //使pList指向连续存储空间的首地址L.pList = (int*)malloc(INIT_SIZE * sizeof(int));L.length = 0;  //目前元素的个数为0L.listSize = INIT_SIZE;  //空间最大存储的数量
}

3、定义插入函数

//第i个元素前插入e
void insert(int e,SqList &L,int i) {if (i <= L.length || L.length < L.listSize) {//将第i个元素开始依次往后移动一个位置,将L[i-1]的位置腾出for (int curIndex = L.length - 1; curIndex >= i - 1; --curIndex) {L.pList[curIndex + 1] = L.pList[curIndex];}L.pList[i - 1] = e;++L.length;  //多存了个数据,元素个数加一}
}

4、定义删除函数

void delete_(SqList &L,int i) {if (i <= L.length || L.length < L.listSize) {//将第i个元素开始依次往后移动一个位置for (int curIndex = i-1; curIndex <= L.length; ++curIndex) {L.pList[curIndex] = L.pList[curIndex + 1];}--L.length;  //多存了个数据,元素个数减一}
}

5、初始化输入表

//初始输入表
void initial_list(SqList* L) {int n,d;printf("请输入输入数字个数n(大于1的整数):");scanf_s("%d", &n);while (1) {if (n <= 0) {printf("请输入大于0的整数!!!");scanf_s("%d", &n);}else {break;}}//printf("%d", n);for (int i = 0; i <= n-1; i++) {printf("请输入第%d个数:",i+1);scanf_s("%d",&d);L->pList[i] = d;}L->length = n;
}

6、定义打印函数

//打印数组
void print_function(SqList L) {for (int i = 0; i < L.length; i++) {printf("%d  ", L.pList[i]);}printf("\n");
}

7、主函数

int main() {SqList L;initial(L);initial_list(&L);printf("原数组:\n");print_function(L);printf("\n");while (1) {printf("请输入0/1/2对线性表进行操作(0是退出,1是插入,2是删除):\n");int num;scanf("%d", &num);if (num == 1) {printf("现在进入插入环节,请指定插入元素与插入位置:\n");int i, n;scanf("%d %d", &i, &n);insert(i, L, n);printf("插入后的数组:\n");print_function(L);}else if (num == 2) {printf("现在进入删除环节,请指定删除要元素位置:\n");int n;scanf("%d",&n);delete_(L, n);printf("删除后的数组:\n");print_function(L);}else if (num == 0) {break;}else {printf("请输入正确的操作(输入0/1/2)\n");}}return 0;
}

运行结果展示

        输入数字个数n,并输入这n个数

        选择下一步操作(0退出,1插入,2删除)

链表

双向链表

        结点有两个指针域:一个指向直接后继,另一个指向直接前驱。目的是克服单链 表的单向寻查的缺点。

插入元素:

        当插入数据元素时,首先生成一个结点,结点的数据域为插入的元素;然后找到元素的插入位置;最后修改指针域。例如下图中,在 p 结点后插入新生 成结点 s,则修改指针的语句为:

s ->data = e; s->next = p->next;  p->next = s;

删除元素:

        当删除数据元素时,仅修改待删除结点的前一个结点的指针。例如下 图中,待删除的结点为 q,q 的前一个结点为 p,删除后结点 q 的数据赋给 e,则修改 指针的语句为:

q= p ->next;  p->next = q->next; e = q-> data;  free(q);

算法实现

1、头文件、结构体的定义

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  
#include <stdlib.h>  typedef struct Node {int data;struct Node* prior;struct Node* next;
} Node;

2、双链表中添加节点

// 在双链表末尾添加节点  
void append(Node** head, int data) {Node* newNode = createNode(data);if (*head == NULL) {*head = newNode;}else {Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;newNode->prior = temp;}
}

3、定义打印函数

// 打印双链表  
void printList(Node* head) {Node* temp = head;while (temp != NULL) {printf("%d ", temp->data);temp = temp->next;}printf("\n");
}

4、指定位置插入元素

// 在指定位置插入节点  
void insertAtPosition(Node** head, int position, int data) {Node* newNode = createNode(data);if (position == 1) {newNode->next = *head;if (*head != NULL) {(*head)->prior = newNode;}*head = newNode;}else {Node* temp = *head;for (int i = 1; temp != NULL && i < position - 1; i++) {temp = temp->next;}if (temp == NULL) {printf("Position out of bounds\n");free(newNode);return;}newNode->next = temp->next;newNode->prior = temp;if (temp->next != NULL) {temp->next->prior = newNode;}temp->next = newNode;}
}

5、删除元素

// 删除指定值的节点  
void deleteValue(Node** head, int data) {Node* temp = *head;Node* prior = NULL;while (temp != NULL && temp->data != data) {prior = temp;temp = temp->next;}if (temp == NULL) {printf("Value not found\n");return;}if (prior == NULL) {*head = temp->next;}else {prior->next = temp->next;}if (temp->next != NULL) {temp->next->prior = prior;}free(temp);
}

6、主函数

int main() {Node* list = NULL;int n, choice, position, data;printf("请输入数字n: ");scanf("%d", &n);printf("请输入%d个数字:\n", n);for (int i = 0; i < n; i++) {int num;scanf("%d", &num);append(&list, num);}printf("当前列表: ");printList(list);printf("请输入1和2选择操作(1:插入 2:删除)\n");scanf("%d", &choice);if (choice == 1) {printf("请输入插入位置和插入的数字: ");scanf("%d %d", &position, &data);insertAtPosition(&list, position, data);}else if (choice == 2) {printf("请输入要删除的数字: ");scanf("%d", &data);deleteValue(&list, data);}else {printf("无效选择\n");}printf("最终列表: ");printList(list);// 释放链表内存  Node* temp;while (list != NULL) {temp = list;list = list->next;free(temp);}return 0;
}

运行结果

        输入数字个数n,并依次输入这n个元素

        选择下一步操作(1插入,2删除)

您的点赞和关注是我持续更新下去的动力!!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode - #139 单词拆分

文章目录 前言摘要1. 描述2. 示例3. 答案题解动态规划的思路代码实现代码解析1. **将 wordDict 转换为 Set**2. **初始化 DP 数组**3. **状态转移方程**4. **返回结果** **测试用例**示例 1:示例 2:示例 3: 时间复杂度空间复杂度总结关于我们 前言 本题由于没有合适答案为以往遗…

【第4章 | 分类与逻辑回归】(python机器学习)

一、逻辑回归 1.1逻辑回归 二项逻辑回归 • Binomial logistic regression model是一种分类模型 • 由条件概率P(Y|X)表示的分类模型 • 形式化为logistic distribution • X取实数&#xff0c;Y取值1,0 特点&#xff1a; • 事件的几率odds&#xff1a;事件发生与事件不发生…

Python毕业设计选题:基于python的豆瓣电影数据分析可视化系统-flask+spider

开发语言&#xff1a;Python框架&#xff1a;flaskPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 系统首页 个人中心 管理员登录界面 管理员功能界面 电影管理 用户管理 系统管理 摘要…

Scala之Array数组

可修改的Array import scala.collection.mutable.ArrayBuffer //Array:数组 //可修改的&#xff1a;ArrayBuffer //不可修改的&#xff1a;Array object Test1 {//可修改的&#xff1a;ArrayBufferdef main(args: Array[String]): Unit {//1.新建val arr1 ArrayBuffer(1,2,3)…

贴代码框架PasteForm特性介绍之select,selects,lselect和reload

简介 PasteForm是贴代码推出的 “新一代CRUD” &#xff0c;基于ABPvNext&#xff0c;目的是通过对Dto的特性的标注&#xff0c;从而实现管理端的统一UI&#xff0c;借助于配套的PasteBuilder代码生成器&#xff0c;你可以快速的为自己的项目构建后台管理端&#xff01;目前管…

麒麟网络负载均衡与高可用方案实践

安装 teamd 包。 yum -y install teamd Copy 一、配置TEAMING 查看两个网卡信息 ifconfig Copy 注意&#xff1a;根据实际网卡设备名称情况调整代码&#xff01;不同环境下网卡名称略有不同&#xff01; 根据查询的结果&#xff0c;两张网卡设备名称分别为 enp0s2 和 enp…

Python学习29天

二分查找 # 定义函数冒泡排序法从大到小排列 def bbble_sort(list):# i控制排序次数for i in range(len(list) - 1):# j控制每次排序比较次数for j in range(len(list) - 1 - i):if list[j] < list[j 1]:list[j], list[j 1] list[j 1], list[j] # 定义二分查找函数 def…

路由协议——iBGP与EBGP

一、适用场景 1、企业需要连接总部与分部&#xff0c;但总部与分部运行着不同的路由协议&#xff0c;总部到分部有自建的专线&#xff0c;端到端的设备支持BGP路由协议。 2、网络运营商&#xff0c;如电信、联通、移动等&#xff0c;各区域的ip路由表庞大&#xff0c;若要完成…

09.事件风暴

学习视频来源&#xff1a;DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid1940048&ctype0 文章目录 概念组成部分具体场景事件风暴寻找聚合 改进具体流程 参考 概念 事件风暴是Alberto Brandolini 发明的一种头脑风暴方法&#x…

蓝队技能-应急响应篇日志自动采集日志自动查看日志自动化分析Web安全内网攻防工具项目

知识点&#xff1a; 1、应急响应-系统日志收集-项目工具 2、应急响应-系统日志查看-项目工具 3、应急响应-日志自动分析-项目工具 演示案例-蓝队技能-工具项目-自动日志采集&自动日志查看&自动日志分析 系统日志自动采集-观星应急工具(Windows系统日志) SglabIr_Co…

【C++】绘制内存管理的地图

生活是属于每个人自己的感受&#xff0c;不属于任何人的看法。 前言 这是我自己学习C的第二篇博客总结。后期我会继续把C学习笔记开源至博客上。 上一期笔记是关于C的类与对象础知识&#xff0c;没看的同学可以过去看看&#xff1a; 【C】面向对象编程的艺术之旅-CSDN博客https…

在 CentOS 系统上直接安装 MongoDB 4.0.25

文章目录 步骤 1&#xff1a;配置 MongoDB 官方源步骤 2&#xff1a;安装 MongoDB步骤 3&#xff1a;启动 MongoDB 服务步骤 4&#xff1a;验证安装步骤 5&#xff1a;可选配置注意事项 以下是在 CentOS 系统上直接安装 MongoDB 4.0.25 的详细步骤&#xff1a; 步骤 1&#x…

core 不可变类型 线程安全 record

当一个类型的对象在创建时被指定状态后&#xff0c;就不会再变化的对象&#xff0c;我们称之为不可变类型。这种类型是线程安全的&#xff0c;不需要进行线程同步&#xff0c;非常适合并行计算的数据共享。它减少了更新对象会引起各种bug的风险&#xff0c;更为安全。 System.D…

OceanBase Shell开放内核运维接口,运维更便捷

DBA在日常业务中面临着繁琐的运维管理任务&#xff0c;亟需高效的工具和灵活的解决方案帮助他们简化操作、提升效率。因此&#xff0c;命令行操作和维护工具&#xff08;CLI工具&#xff09;&#xff0c;因其高效、灵活、可远程管理以及技术深度等特点&#xff0c;成为DBA和开发…

基于Amazon Bedrock:一站式多模态数据处理新体验

目录 引言 关于Amazon Bedrock 基础模型体验 1、进入环境 2、发现模型及快速体验 3、打开 Amazon Bedrock 控制台 4、通过 Playgrounds 体验模型 &#xff08;1&#xff09;文本生成 &#xff08;2&#xff09;图片生成 关于资源清理 结束语 引言 在云计算和人工智能…

go 学习网站,go例子 go demo go学习视频

1. 代码例子&#xff1a; Go by Example 2. b站 视频&#xff1a; 尚硅谷视频&#xff1a; 004_尚硅谷_程序的基本概念_哔哩哔哩_bilibili 3. go技术文档&#xff1a; fmt Go语言中文文档

Django基础配置

一.前言 前面我们说完了前端基础&#xff0c;现在我们开始讲后端框架了&#xff0c;我们今天说的是django&#xff0c;当然今天主要还是和大家了解一下框架和django的基础配置 二.web框架 2.1 web框架初始 在我们学习web框架的时候&#xff0c;我们首先得了解到web框架的本…

Hive分桶超详细!!!

1、分桶的意义 数据分区可能导致有些分区,数据过多&#xff0c;有些分区,数据极少。分桶是将数据集分解为若干部分(数据文件)的另一种技术。 分区和分桶其实都是对数据更细粒度的管理。当单个分区或者表中的数据越来越大&#xff0c;分区不能细粒度的划分数据时&#xff0c;我…

【AI大模型引领变革】探索AI如何重塑软件开发流程与未来趋势

文章目录 每日一句正能量前言流程与模式介绍【传统软件开发 VS AI参与的软件开发】一、传统软件开发流程与模式二、AI参与的软件开发流程与模式三、AI带来的不同之处 结论 AI在软件开发流程中的优势、挑战及应对策略AI在软件开发流程中的优势面临的挑战及应对策略 结论 后记 每…

根据条件 控制layui的table的toolbar的按钮 显示和不显示

部分代码&#xff1a; <!-----查询条件-----> <input type"date" id"StartDate" onchange"PageList()" /> <input type"date" id"EndDate" onchange"PageList()" /><!-----表格Table-----&…