C++实现单向链表操作(实验3--作业)

news2024/11/17 15:32:48

一、单向链表介绍

单向链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据域和一个指向下一个节点的指针域。

  1. 结构特点

    • 单向链表的节点通过指针链接在一起,形成一个线性的数据结构。
    • 链表的头节点通常是一个特殊的节点,它不存储实际的数据,只用于指向链表的第一个存储数据的节点。
    • 每个节点的指针指向下一个节点,最后一个节点的指针为NULL,表示链表的结束。
  2. 优点

    • 动态内存分配:可以根据需要动态地添加和删除节点,不需要预先确定链表的大小。
    • 插入和删除操作高效:在链表中间插入或删除节点只需要修改几个指针,时间复杂度为 O ( 1 ) O(1) O(1)(在已知插入或删除位置的情况下)。
  3. 缺点

    • 随机访问困难:不像数组可以通过下标直接访问元素,在链表中访问特定位置的元素需要从头节点开始遍历,时间复杂度为 O ( n ) O(n) O(n)
  4. 常见操作

    • 初始化:创建一个空链表,通常包括创建头节点并将其指针域设置为NULL
    • 插入节点:可以在链表的头部、尾部或特定位置插入新节点。
    • 删除节点:根据给定的条件删除链表中的节点。
    • 查找节点:在链表中查找具有特定值的节点。
    • 遍历链表:从头到尾遍历链表,访问每个节点的数据。

二、代码总结

这段 C++代码实现了一个单向链表的多种操作,包括初始化、插入、删除、查找、排序、合并和逆置等功能。

  1. 功能模块

    • 初始化和销毁
      • LinkedListInit函数用于初始化一个空链表,创建头节点并分配内存。
      • LinkedListDestroy函数用于销毁链表,释放每个节点的内存空间。
      • LinkedListClear函数用于置空链表,删除链表中的所有节点,但保留头节点。
    • 插入操作
      • LinkedListAddHead函数实现头插法,在链表头部插入新节点。
      • LinkedListAddTail函数实现尾插法,在链表尾部插入新节点。
      • LinkedListInsert函数按序号在链表中插入新节点。
    • 删除操作
      • LinkedListDelete函数按序号删除链表中的节点。
    • 查找操作
      • LinkedListFind函数按值在链表中查找节点。
    • 打印操作
      • LinkedListPrint函数用于打印链表中的所有节点。
    • 排序操作
      • LinkedListSort函数实现冒泡排序,对链表中的节点进行排序。
    • 合并操作
      • LinkedListMerge函数将两个有序链表合并为一个有序链表。
    • 逆置操作
      • LinkedListReverse函数实现链表的原地逆置。
  2. 整体流程

    • main函数中,首先初始化两个链表L1L2,分别通过头插法和尾插法创建链表。
    • 然后对L2进行插入和删除操作,对L1进行插入和删除操作。
    • 接着对L1L2进行排序。
    • 之后创建一个新的链表MergeList,并将L1L2合并到MergeList中。
    • 最后在MergeList中查找特定值,并对MergeList进行原地逆置操作。
    • 最后销毁所有链表,释放内存。

下列是我的代码演示

#include<bits/stdc++.h>
using namespace std;

#define MAXSIZE 100 
#define OVERFLOw -2
#define OK 1
#define ERROR 0

typedef int Status;
typedef int eleType;
typedef struct LNode {
	eleType data;
	struct LNode *next;
} LNode, *LinkList;

/*
初始化一个空链表							OK
链表的置空和销毁							OK
前插法建表、后插法建表						OK
能够在链表中实现元素的查找、插入和删除		OK
能够输出链表的全部元素						OK
链表元素的排序及有序链表的合并(选做)		OK
链表的原地逆置(选做)						OK
*/

//初始化一个空链表
Status LinkedListInit(LinkList &L){
	L = new LNode;
	if(!L) exit(OVERFLOw);
	L->next = NULL;
	return OK;
}

//链表的销毁
Status LinkedListDestroy(LinkList &L){
	while(L){
		LinkList temp = L;
		L = L->next;
		delete temp;
	}
	return OK;
}

//链表的置空
Status LinkedListClear(LinkList &L){
	LinkList p = L->next;
	while(p){
		LinkList temp = p;
		p = p->next;
		delete temp;
	}
	L->next = NULL;
	return OK;
}

//头 插 法
void LinkedListAddHead(LinkList &L,eleType value){
	LNode * newNode = new LNode;
	newNode->data = value;
	newNode ->next = L->next;
	L->next = newNode ;
}

//尾 插 法
void LinkedListAddTail(LinkList &L, eleType value) {
	LNode* p = L;
	LNode* newNode = new LNode;
	newNode->data = value;
	while (p->next!= NULL) {
		p = p->next;
	}
	newNode->next = p->next;
	p->next = newNode;
}

//按值查找
LNode * LinkedListFind(LinkList &L,eleType value) {
	LNode * p = L->next;
	int i = 1;
	while(p){
		if(p->data==value){
			cout<<"在链表中找到 "<<value<<",位置在第"<<i<<"个处"<<endl<<endl;
			return p;
		}
		p=p->next;
		i++;
	}
	cout<<"没找到"<<value<<endl<<endl;
	return p;
}

//按序号 插 入
Status LinkedListInsert(LinkList &L,int index,eleType value){
	LNode * p = L ;
	LNode * NewNode = new LNode;
	NewNode ->data = value;
	int i = 0;
	while(i<index-1){
		p = p->next;
		i++;
	}
	NewNode->next = p->next;
	p->next = NewNode;
	cout<<"成功将元素:"<<value<<"  插 在第 "<<index<<" 个元素处"<<endl;
	return OK;
}

//元素 删除 
Status LinkedListDelete(LinkList &L,int index){
	if (index == 0) {
		L->next = L->next->next;
		cout<<"成功 删除 第"<<index<<"个元素"<<endl;
		return OK;
	}
	int i = 0;
	LNode * p = L;
	while(i<index-1 && p->next){
		p = p->next;
		i++;
	}
	if(!(p->next) || i>index-1)    return ERROR;  
	LNode* temp = p->next;
	p->next = p->next->next;
	cout<<"成功 删除 第"<<index<<"个元素: "<<temp->data<<endl;
	delete temp;
	return OK;
}

//打印链表
void LinkedListPrint(LinkList &L){
	LNode* p = L->next;
	while(p){
		cout<<p->data<<"->";
		p = p->next;
	}
	cout<<"NULL"<<endl<<endl;
}

//链表的排序(冒泡排序)
void LinkedListSort(LinkList &L){
	if(L==NULL||L->next==NULL) return ;//没有元素或者只有一个元素
	bool swapped;//看是否完成交换 当swapped为false时代表排序OK
	LNode * ptr ;//游离 遍历 交换
	LNode * lptr = NULL;//已经交换过的
	do{
		//每一次排序把未排序过的最大的放到了最后面
		//更新指针为排好序的元素的头一个节点
		swapped = false;
		ptr = L->next;//从头节点开始
		while(ptr->next!=lptr)//不到最后一个未排序的元素
		{
			if(ptr->data > ptr->next->data){
				//交换
				eleType temp = ptr->next->data;
				ptr->next->data = ptr->data;
				ptr->data = temp;
				swapped = true;
			}
			ptr = ptr->next;
		}
		lptr = ptr;
	}while(swapped);
}

// 有序链表的合并
void LinkedListMerge(LinkList L1, LinkList L2, LinkList& result) {
	LNode* p1 = L1->next; // 指向 L1 头节点
	LNode* p2 = L2->next; // 指向 L2 头节点
	while (p1 && p2) {
		if (p1->data < p2->data) {
			LinkedListAddTail(result,p1->data);
			p1=p1->next;
		} else if (p2->data < p1->data) {
			LinkedListAddTail(result,p2->data);
			p2 = p2->next;
		} else {
			LinkedListAddTail(result,p1->data);
			p1 = p1->next;
			p2 = p2->next;
		}
	}
	while (p1) {
		LinkedListAddTail(result,p1->data);
		p1=p1->next;
	}
	while (p2) {
		LinkedListAddTail(result,p2->data);
		p2 = p2->next;
	}
}
//                               首节点↓
//链表的原地逆置(适用于带头节点 即 L->①->②->③->…->NULL)
//                           头节点↑
void LinkedListReverse(LinkList &L){
	LNode * beg = L->next;//首节点
	LNode * end = L->next->next;
	while(end!=NULL){
		beg->next = end->next;//连 连上后面的 以防调转的目标节点之后节点素丢失
		end->next = L->next;//掉 掉转的目标节点的后继指向目前的首节点(目标节点将成为新的首节点)
		L->next = end;//接 头节点的后继为新的首节点
		end = beg->next;//移 end始终是beg后面一个节点
	}
}
int main(){
	LinkList L1;
	LinkedListInit(L1);
	LinkedListAddHead(L1,1);
	LinkedListAddHead(L1,2);
	LinkedListAddHead(L1,3);
	LinkedListAddHead(L1,4);
	LinkedListAddHead(L1,5);
	cout<<"头 插 法得到L1 :"<<endl;
	LinkedListPrint(L1);
	
	LinkList L2;
	LinkedListInit(L2);
	LinkedListAddTail(L2,7);
	LinkedListAddTail(L2,6);
	LinkedListAddTail(L2,5);
	LinkedListAddTail(L2,4);
	LinkedListAddTail(L2,3);
	cout<<"尾 插 法得到L2 :"<<endl;
	LinkedListPrint(L2);
	
	cout<<"对L2进行操作: ";
	LinkedListInsert(L2,1,36);
	LinkedListPrint(L2);
	
	cout<<"对L2进行操作: ";
	LinkedListDelete(L2,4);
	LinkedListPrint(L2);
	
	cout<<"对L1进行操作: ";
	LinkedListInsert(L1,3,17);
	LinkedListPrint(L1);
	
	cout<<"对L1进行操作: ";
	LinkedListDelete(L1,3);
	LinkedListPrint(L1);
	
	LinkedListSort(L1);
	cout<<"排序后的 L1:";
	LinkedListPrint(L1);
	
	LinkedListSort(L2);
	cout<<"排序后的 L2:";
	LinkedListPrint(L2);
	
	cout<<"L1 L2 合并后 得 MergeList : "<<endl;
	LinkList MergeList ;
	LinkedListInit(MergeList);
	LinkedListMerge(L1,L2,MergeList);
	LinkedListPrint(MergeList);
	
	cout<<"对MergeList进行操作: ";
	LinkedListFind(MergeList,5);
	
	cout<<"MergeList 原地逆置后"<<endl;
	LinkedListReverse(MergeList);
	LinkedListPrint(MergeList);
	
	
	LinkedListDestroy(L1);
	LinkedListDestroy(L2);
	LinkedListDestroy(MergeList);
	
	return 0;
}

运行结果如下
在这里插入图片描述

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

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

相关文章

【Google Chrome Windows 64 version及 WebDriver 版本】

最近升级到最新版本Chrome后发现页面居然显示错乱实在无语, 打算退回原来的版本, 又发现官方只提供最新的版本下载, 为了解决这个问题所有收集了Chrome历史版本的下载地址分享给大家. Google Chrome Windows version 64 位 VersionSize下载地址Date104.0.5112.10282.76 MBhtt…

leetcode 2398.预算内的最多机器人数目

2398.预算内的最多机器人数目 题意&#xff1a; 解析&#xff1a; 需要注意的是&#xff0c;题目询问中连续是子数组的意思&#xff0c;即求满足条件的最长子数组的长度。 因为是连续的&#xff0c;所以可以用双指针扫描整个数组。每次将右指针 r r r 向右移动一个位置&…

Vue的缓存组件 | 详解KeepAlive

引言 在Vue开发中&#xff0c;我们经常需要处理大量的组件渲染和销毁操作&#xff0c;这可能会影响应用的性能和用户体验。而Vue的KeepAlive组件提供了一种简便的方式来优化组件的渲染和销毁流程&#xff0c;通过缓存已经渲染的组件来提升应用的性能。 本文将详细介绍Vue的Ke…

2024年职场人士PDF转换的新宠儿

PDF文件已经成为日常收发文件的首选项了&#xff0c;它能保证文件页面内容、版式的统一性&#xff0c;但是不太好编辑&#xff0c;所以我们还需要一些小工具来帮我们解决这个问题。今天我们来探讨一下有什么可以从pdf转换器免费版官网下载的工具。 1.Foxit PDF转换大师 链接一…

BuripSuiteProfessional 抓取HTTPS配置

1.电脑拿开代理 谷歌为例 点击三点-设置 -输入代理--点击代理设置 打开手动代理---IP ,端口如图-点击保存 2.下载CA证书 打开代理后,谷歌浏览器打开,输入/burp--如下图-点击CA证书下载证书 选择下载目录--桌面 3.安装CA证书 谷歌浏览器中点开设置-输入证书-点击安全 点击…

Apollo(阿波罗)架构由浅入深剖析

1.最简架构 如果不考虑分布式微服务架构中的服务发现问题,Apollo 的最简架构如下图所示: 注意事项: ConfigService 是一个独立的微服务,服务于 Client 进行配置获取。 Client 和 ConfigService 保持长连接,通过一种拖拉结合 (push & pull) 的模式,实现配置实时更新…

【鸿蒙】HarmonyOS NEXT星河入门到实战8-自定义组件-组件通信

目录 1、模块化语法 1.1 模块化基本认知 1.2 默认导出和导入 1.2.1 在ets下新建tools目录 1.2.2 在tools下新建moduls.ets文件 1.2.3 index.ets 1.3 按需导出和导入 1.4 全部导入 2、自定义组件 -基础 2.1 自定义组件 - 基本使用 2.2 自定义组件 -通用样式 2.2.1 et…

Wophp靶场寻找漏洞练习

1.命令执行漏洞 打开网站划到最下&#xff0c;此处的输入框存在任意命令执行漏洞 输入命令whoami 2.SQL注入 搜索框存在SQL注入&#xff0c;类型为整数型 最终结果可以找到管理员账户和密码 3.任意文件上传漏洞 在进入管理员后台后&#xff0c;上传木马文件 访问该文件&…

【智路】智路OS airos-edge

欢迎来到智路OS https://gitee.com/ZhiluCommunity/airos-edge 智路OS是全球首个开源开放的智能网联路侧单元操作系统&#xff08;简称“智路OS”&#xff09;&#xff0c; 是以高等级自动驾驶技术为牵引&#xff0c;沉淀出来的“车路云网图”一体化的智能交通基础软件平台。…

基于SpringBoot+Vue的智慧自习室预约管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

基于vue框架的宠物店管理系统的设计与实现4czn0(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,商品分类,服务类型,商品信息,商品订单,宠物服务,服务预约,服务评价,商品咨询 开题报告内容 基于Vue框架的宠物店管理系统的设计与实现开题报告 一、引言 随着宠物行业的蓬勃发展&#xff0c;宠物店作为宠物产品与服务的重要提供…

神经网络通俗理解学习笔记(2)循环神经网络RNN

循环神经网络RNN 序列建模自回归模型隐变量自回归模型 文本数据预处理循环神经网络随时间反向传播循环神经网络代码实现RNN的长期依赖问题 序列建模 序列数据-时间 不同时间上收集到的数据&#xff0c;描述现象随时间变化的情况 时间序列分析是指从时间排列的数据点中抽取有价…

Linux下编译Kratos

本文记录在Linux下编译Kratos的流程。 零、环境 操作系统Ubuntu 22.04.4 LTSVS Code1.92.1Git2.34.1GCC11.4.0CMake3.22.1Boost1.74.0oneAPI2024.2.1 一、依赖与代码 1.1 安装依赖 apt-get update apt-get install vim openssh-server openssh-client ssh \build-essential …

Web:HTTP包的相关操作

目录 一、请求包修改页面来源 二、Cookie身份认证 三、XXF修改本地访问 四、向页面同时发出GET和POST请求 一、请求包修改页面来源 题目提示要从 http://localhost:8080/flag3cad.php?a1&#xff0c;请求包中没有指定请求来源&#xff0c;需要指定。 而表示页面来源的字段…

cv2.bitwise_or 提取ROI区域

原图如下所示&#xff0c;想提取圆形ROI区域&#xff0c;红色框 img np.ones(ori_img.shape, dtype"uint8") img img * 255 cv2.circle(img, (50,50), 50, 0, -1) self.bitwiseOr cv2.bitwise_or(ori_img, circle)使用一个和原图尺寸一致的图像做mask,图白圆黑 以…

【Echarts】vue3打开echarts的正确方式

ECharts 是一个功能强大、灵活易用的数据可视化工具&#xff0c;适用于商业报表、数据分析、科研教育等多种场景。那么该如何优雅的使用Echarts呢? 这里以vue3为例。 安装echarts pnpm i echarts封装公用方法 // ts-nocheck import * as echarts from echarts; // 我们这里借…

Naive UI中的时间选择器如何禁止选择今天之前的时间

:is-date-disabled"dateDisabled"<n-date-pickerv-if"formData.timeEndActive"type"date"style"width: 100%"placeholder"请选择任务结束时间"value-format"yyyy-MM-dd 23:59:59":is-date-disabled"dateD…

mysql-搭建主从复制

文章目录 1、准备主服务器2、准备从服务器3、主库配置3.1、创建MySQL主服务器配置文件&#xff1a; 4、从库配置5、搭建主从&测试5.1、使用命令行登录MySQL主服务器5.2、主机中查询master状态&#xff1a;5.3、从机中查询slave状态&#xff1a;5.4、主机中创建slave用户&am…

CSP-J算法基础 树状结构与二叉树

文章目录 前言树状结构树状结构的基本概念&#xff1a;为什么需要树状结构&#xff1f;优点树状结构的示例 二叉树什么是二叉树&#xff1f;二叉树的类型什么样的树不是二叉树&#xff1f;二叉树的五种形态 完全二叉树相关概念完全二叉树的定义&#xff1a; 相关概念1. **高度&…

SAAS智慧工地源码,建筑行业数字化管理云平台系统

智慧工地是建筑行业数字化转型的重要组成部分&#xff0c;它通过集成物联网、大数据、云计算、人工智能等现代信息技术&#xff0c;对建筑工地进行智能化管理&#xff0c;以提高施工效率、保障施工安全、控制施工成本、提升施工质量。 以下是智慧工地的主要特点和应用&#xff…