当前位置: 首页 > news >正文

数据结构——实验01-线性表的链式存储和操作

一、实验内容

二、算法思想与算法实现

1、解题思想

(1)逆序创建链表La就是使用头插法创建一个链表,所谓头插法就是在创建链表时始终将新元素插入到头结点之后,而正序创建链表Lb就是使用尾插法创建一个链表,所谓尾插法创建一个链表就是在创建链表时始终将新元素插入到表尾

(2)合并两个升序序列,这个算法很基础,这里不做叙述,需要注意的是由于在创建La时我们是逆序创建的,也就是说此时La是降序排列,所以在做两个链表的合并操作之前我们需要先将链表La逆置

(3)删除Lc中的多余元素:这里我们可以用一个指针p表示当前链表的结点,然后用一个指针t指向第一个结点元素值不等于当前结点元素值的结点,然后让结点p的next指针域指向t即可,如下图所示

(4)逆置一个链表,可以借助头插法创建链表的思想,即扫描当前需要逆置的链表不断将当前结点插入到表头

2、算法实现

(1)定义链表结点

//定义链表节点
typedef struct LNode {int data;                          //数据域struct LNode* next;                //指针域
}LNode,*LinkList;

(2)头插法创建链表

//使用头插法创建一个带头结点的链表,当用户输入666时表示链表创建结束
bool List_HeadInsert(LinkList& L) {//对链表进行初始化操作L = (LNode*)malloc(sizeof(LNode) * 1);if (L == NULL){return false;}L->next = NULL;LNode* p = NULL;int inputs = 0;printf("请输入链表元素:\n");while (1){scanf("%d", &inputs);if (inputs == 666)break;p = (LNode*)malloc(sizeof(LNode) * 1);if (p == NULL){return false;}p->data = inputs;p->next = L->next;L->next = p;}return true;
}

 (3)尾插法创建链表


//使用尾插法创建一个带头结点的链表,当用户输入666时表示链表创建结束
bool List_TailInsert(LinkList& L)
{//对链表进行初始化操作L = (LNode*)malloc(sizeof(LNode) * 1);if (L == NULL)return false;L->next = NULL;LNode* p, * t;   //p指针用于建立新结点,t用于指向当前链表的尾结点int inputs;t = L;printf("请输入链表元素:\n");while (1){scanf("%d", &inputs);if (inputs == 666)break;p = (LNode*)malloc(sizeof(LNode) * 1);if (p == NULL)return false;p->data = inputs;p->next = NULL;t->next = p;t = p;}return true;
}

(4)合并两个升序链表

//合并两个有序链表
bool Merge_SortedLinkList(LinkList La, LinkList Lb, LinkList& Lc)
{LNode* a, * b, * c, * t;a = La->next;b = Lb->next;//初始化链表Lc;Lc = (LNode*)malloc(sizeof(LNode) * 1);if (Lc == NULL)return false;Lc->next = NULL;t = Lc;          //t指针指向Lc的尾部结点while (a != NULL && b != NULL){c = (LNode*)malloc(sizeof(LNode) * 1);if (c == NULL)return false;if (a->data <= b->data){c->data = a->data;c->next = NULL;t->next = c;t = c;a = a->next;}else{c->data = b->data;c->next = NULL;t->next = c;t = c;b = b->next;}}while (a == NULL && b != NULL){c = (LNode*)malloc(sizeof(LNode) * 1);c->data = b->data;c->next = NULL;t->next = c;t = c;b = b->next;}while (b == NULL && a != NULL){c = (LNode*)malloc(sizeof(LNode) * 1);c->data = a->data;c->next = NULL;t->next = c;t = c;a = a->next;}return true;
}

(5)删除链表中的重复元素

//删除有序链表中的重复元素
bool DeleteRpeatElem(LinkList& L)
{//判断是否是空表if (L->next == NULL)return false;LNode* p, * e = NULL;   //p指针用于记录当前结点,e指针用于表示值等于当前结点的最后一个结点p = L->next;while (p != NULL){e = p->next;if (e == NULL)break;while (p->data == e->data){LNode* temp = e;e = e->next;free(temp);}p->next = e;p = p->next;	}return true;
}

(6)逆置一个链表

//逆置一个链表,从头开始扫描一个链表,不断将当前结点插入到链表的开始位置
bool ReverseLinkList(LinkList& L)
{if (L->next == NULL)return false;LNode* end = L->next;  //指向逆置以后的表尾元素LNode* p = end->next;  //指向当前元素while (p != NULL){LNode* temp = p->next;p->next = L->next;L->next = p;p = temp;}end->next = NULL;return true;
}

三、代码测试

完整测试代码:

//用C语言编写程序,其中Lb={2,4,6,8,10} La={1,2,3,4,5,6,8},
//(1)逆序创建链表La, 正序创建链表Lb; .
//(2)将La与Lb有序合并,得到有序链表Lc:Lc = { 1,2,2,3,4,4,5,6,6,8,8,10 }
//(3)删除Lc中多余的重复元素,使得所有元素只保留一个;
//(4)将链表Lc倒置,并输出其内容。#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
using namespace std;//定义链表节点
typedef struct LNode {int data;                          //数据域struct LNode* next;                //指针域
}LNode,*LinkList;//使用头插法创建一个带头结点的链表,当用户输入666时表示链表创建结束
bool List_HeadInsert(LinkList& L) {//对链表进行初始化操作L = (LNode*)malloc(sizeof(LNode) * 1);if (L == NULL){return false;}L->next = NULL;LNode* p = NULL;int inputs = 0;printf("请输入链表元素:\n");while (1){scanf("%d", &inputs);if (inputs == 666)break;p = (LNode*)malloc(sizeof(LNode) * 1);if (p == NULL){return false;}p->data = inputs;p->next = L->next;L->next = p;}return true;
}//使用尾插法创建一个带头结点的链表,当用户输入666时表示链表创建结束
bool List_TailInsert(LinkList& L)
{//对链表进行初始化操作L = (LNode*)malloc(sizeof(LNode) * 1);if (L == NULL)return false;L->next = NULL;LNode* p, * t;   //p指针用于建立新结点,t用于指向当前链表的尾结点int inputs;t = L;printf("请输入链表元素:\n");while (1){scanf("%d", &inputs);if (inputs == 666)break;p = (LNode*)malloc(sizeof(LNode) * 1);if (p == NULL)return false;p->data = inputs;p->next = NULL;t->next = p;t = p;}return true;
}//合并两个有序链表
bool Merge_SortedLinkList(LinkList La, LinkList Lb, LinkList& Lc)
{LNode* a, * b, * c, * t;a = La->next;b = Lb->next;//初始化链表Lc;Lc = (LNode*)malloc(sizeof(LNode) * 1);if (Lc == NULL)return false;Lc->next = NULL;t = Lc;          //t指针指向Lc的尾部结点while (a != NULL && b != NULL){c = (LNode*)malloc(sizeof(LNode) * 1);if (c == NULL)return false;if (a->data <= b->data){c->data = a->data;c->next = NULL;t->next = c;t = c;a = a->next;}else{c->data = b->data;c->next = NULL;t->next = c;t = c;b = b->next;}}while (a == NULL && b != NULL){c = (LNode*)malloc(sizeof(LNode) * 1);c->data = b->data;c->next = NULL;t->next = c;t = c;b = b->next;}while (b == NULL && a != NULL){c = (LNode*)malloc(sizeof(LNode) * 1);c->data = a->data;c->next = NULL;t->next = c;t = c;a = a->next;}return true;
}//删除有序链表中的重复元素
bool DeleteRpeatElem(LinkList& L)
{//判断是否是空表if (L->next == NULL)return false;LNode* p, * e = NULL;   //p指针用于记录当前结点,e指针用于表示值等于当前结点的最后一个结点p = L->next;while (p != NULL){e = p->next;if (e == NULL)break;while (p->data == e->data){LNode* temp = e;e = e->next;free(temp);}p->next = e;p = p->next;	}return true;
}//逆置一个链表,从头开始扫描一个链表,不断将当前结点插入到链表的开始位置
bool ReverseLinkList(LinkList& L)
{if (L->next == NULL)return false;LNode* end = L->next;  //指向逆置以后的表尾元素LNode* p = end->next;  //指向当前元素while (p != NULL){LNode* temp = p->next;p->next = L->next;L->next = p;p = temp;}end->next = NULL;return true;
}//顺序打印一个链表中的所有元素
bool PrintLinkList(LinkList L)
{if (L->next == NULL)return false;LNode* p = L->next;while (p != NULL){printf("%d\t", p->data);p = p->next;}printf("\n");return true;
}//测试程序
int main()
{LinkList La, Lb, Lc;//逆序创建链表La,即使用头插法创建链表LaList_HeadInsert(La);printf("链表La:\n");PrintLinkList(La);//正序创建链表Lb,即使用尾插法创建链表LbList_TailInsert(Lb);printf("链表Lb:\n");PrintLinkList(Lb);//合并La和Lb//先逆序LaReverseLinkList(La);printf("逆序后的链表La:\n");PrintLinkList(La);//调用函数合并La和LbMerge_SortedLinkList(La, Lb, Lc);printf("合并链表La和链表Lb得到的链表Lc:\n");PrintLinkList(Lc);//删除Lc中的重复元素DeleteRpeatElem(Lc);printf("删除链表Lc中的重复元素的结果:\n");PrintLinkList(Lc);//将Lc逆序ReverseLinkList(Lc);printf("将链表Lc逆序之后的结果:\n");PrintLinkList(Lc);return 0;}

测试结果截图:

相关文章:

数据结构——实验01-线性表的链式存储和操作

一、实验内容 二、算法思想与算法实现 1、解题思想 &#xff08;1&#xff09;逆序创建链表La就是使用头插法创建一个链表&#xff0c;所谓头插法就是在创建链表时始终将新元素插入到头结点之后&#xff0c;而正序创建链表Lb就是使用尾插法创建一个链表&#xff0c;所谓尾插法…...

十分钟上手vue!

Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;Vue 都可以胜任。 一 vue.js的导入及使用 vue安装…...

day37WEB攻防-通用漏洞XSS跨站权限维持钓鱼捆绑浏览器漏洞

目录 XSS-后台植入 Cookie&表单劫持&#xff08;权限维持&#xff09; 案例演示 XSS-Flash 钓鱼配合 MSF 捆绑上线 1、生成后门 2、下载官方文件-保证安装正常 3、压缩捆绑文件-解压提取运行 4、MSF 配置监听状态 5、诱使受害者访问 URL-语言要适当 XSS-浏览器网马…...

【Java程序设计】【C00215】基于SSM的勤工助学管理系统(论文+PPT)

基于SSM的勤工助学管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这个一个基于SSM的勤工助学管理系统&#xff0c;本系统共分为三种权限&#xff1a;管理员、教师和学生 管理员&#xff1a;首页、个人中心、教师管理、学生管理…...

c#的反汇编对抗

文章目录 前记nim攻防基础FFI内存加载加解密、编码 后记C#类型转换表nim基础 前记 随便编写一个c#调用winapi并用vs生成dll,同时用csc生成exe using System; using System.Runtime.InteropServices; namespace coleak {class winfun{[DllImport("User32.dll")]publ…...

设计模式之框架源码剖析(实战+图解)

Java设计模式 1&#xff0c;概述 随着软件开发人员人数的增多&#xff0c;一些公司急需一些高端人才。作为一个高端人才&#xff0c;设计面向对象软件是必不可少的能力&#xff0c;而软件设计是需要很深的功力&#xff0c;设计模式就要求你必须掌握。 2&#xff0c;本章特色…...

SQL注入:sqli-labs靶场通关(1-37关)

SQL注入系列文章&#xff1a; 初识SQL注入-CSDN博客 SQL注入&#xff1a;联合查询的三个绕过技巧-CSDN博客 SQL注入&#xff1a;报错注入-CSDN博客 SQL注入&#xff1a;盲注-CSDN博客 SQL注入&#xff1a;二次注入-CSDN博客 ​SQL注入&#xff1a;order by注入-CSDN博客 …...

浙政钉(专有钉钉)

专有钉钉是浙政钉的测试版本&#xff0c;可在正式发布之前进行业务开发。 专有钉钉 原名政务钉钉 是高安全、强管控、灵活开放的面向大型组织专有独享的协同办公平台。支持专有云、混合云等多种方式灵活部署&#xff0c;以满足客户特定场景所需为目标&#xff0c;最大化以“平…...

【lesson2】定长内存池的实现

文章目录 介绍定长内存池的设计定长内存池的实现需要成员变量需要的成员函数定长内存池结构定长内存池Delete&#xff08;释放空间&#xff09;的实现定长内存池New&#xff08;申请空间&#xff09;的实现 定长内存池的实现完整版 介绍 作为程序员(C/C)我们知道申请内存使用的…...

C++迷宫游戏详解

个人主页&#xff1a;[PingdiGuo_guo] 收录专栏&#xff1a;[C干货专栏] 大家好呀&#xff0c;我是PingdiGuo_guo&#xff0c;今天我们来学习用C实现一个迷宫游戏。 目录 1.迷宫的具体步骤 1.1.迷宫的初始化 1.2.寻路算法 1.DFS算法 2.BFS算法 1.3.移动 2.总结 C迷宫游…...

java下载网络文件

/*** 下载文件** param fileId* param response* throws Exception*/ GetMapping("/downLoadFile") public void downLoadFile(Long fileId, HttpServletResponse response) throws Exception{// 根据文件ID查询文件路径FileDO fileDO fileService.get(fileId);// 定…...

大数据信用报告查询费用一般要多少钱?

一些不少朋友在申贷的时候被拒贷之后&#xff0c;得到的原因就是因为大数据不良被拒&#xff0c;这时候很多人都反过来查询自己的大数据信用报告&#xff0c;而查询的价格也是不少朋友都比较关注的&#xff0c;那大数据信用报告查询费用一般要多少钱呢?下面本文就为你介绍一下…...

【操作宝典】IntelliJ IDEA新建maven项目详细教程

目录 &#x1f33c;1. 配置maven环境 &#x1f33c;2. 创建maven项目 &#x1f33c;3. 创建maven项目完整示例 a. 导入spring boot环境 b. 修改maven配置 c. 下载jar包 d. 创建Java类 &#x1f33c;1. 配置maven环境 【安装指南】maven下载、安装与配置详细教程-CSDN博客…...

【Java程序设计】【C00196】基于(JavaWeb+SSM)的旅游管理系统(论文+PPT)

基于&#xff08;JavaWebSSM&#xff09;的旅游管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的旅游平台 本系统分为前台、管理员2个功能模块。 前台&#xff1a;当游客打开系统的网址后&#xff0c;首先看到的…...

pdmodel从动态模型转成静态onnx

1.下载项目 git clone https://github.com/jiangjiajun/PaddleUtils.git 2.新建两个新的文件夹 第一个文件夹放两个必要文件 第二个文件夹可以设置为空&#xff0c;用来存放转换后的模型 如图&#xff1a; 3.在终端运行 python paddle/paddle_infer_shape.py --model_dir …...

git 如何修改仓库地址

问题背景&#xff1a;组内更换大部门之后&#xff0c;代码仓的地址也迁移了&#xff0c;所以原来的git仓库地址失效了。 虽然重新建一个新的文件夹&#xff0c;再把每个项目都git clone一遍也可以。但是有点繁琐&#xff0c;而且有的项目本地还有已经开发一半的代码&#xff0c…...

基于springboot篮球论坛系统源码和论文

首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设计。本项…...

【三维重建】运动恢复结构(SfM)

运动恢复结构是通过三维场景的多张图像&#xff0c;恢复出该场景的三维结构信息以及每张图片对应的摄像机参数。 欧式结构恢复(内参已知&#xff0c;外参未知) 欧式结构恢复问题&#xff1a; 已知&#xff1a;1、n个三维点在m张图像中的对应点的像素坐标 2、相机内参 求解&…...

Android Studio非UI线程修改控件——定时器软件

目录 一、UI界面设计 1、UI样式 2、XML代码 二、功能编写 1、定义 2、实现方法 3、功能实现 一、UI界面设计 1、UI样式 2、XML代码 <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android…...

canvas的一些基础

在 Canvas 中&#xff0c;基本图形有两种&#xff1a;直线图形和曲线图形 直线图形&#xff1a;直线、矩形(描边矩形和填充矩形)、多边形 曲线图形&#xff1a;曲线和弧线&#xff08;弧线是圆的一部分&#xff0c;曲线则不一定&#xff0c;弧线上的每个点都具有相同的曲率&…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...