链表操作总结-包括链表合并、插入删除、清空复制、逆序

C++链表实现职工信息管理系统:从数据结构到工程实践 链表作为一种基础且重要的数据结构,是理解计算机内存管理和数据组织的关键。其核心原理是通过节点和指针实现动态、非连续的数据存储,每个节点包含数据和指向下一个节点的指针。这种结构在频繁进行插入和删除操作的场景下,相比数组具有显著的时间复杂度优势(O(1)的插入/删除)。在工程实践中,手动实现链表是深入掌握C++指针操作、内存分配(new/delete)和面向对象编程的绝佳途径。通过构建一个完整的职工信息管理系统,开发者能将理论应用于实战,涵盖结构体设计、文件I/O、排序算法等综合技能,这正是巩固C++核心语法和 阅读详情

A. 关于有序表合并操作
线性结构合并操作可以分为两类,一类是顺序表(顺序存储),另一类是链表(链式存储),二者在有序表合并时的操作并不完全相同。详细分析如下:
①顺序表:由于顺序表属于顺序存储结构,当需要插入或删除表中元素时需要移动该位置后续的各元素,所以按通常方法,应开辟一个临时的存储表,用于存放合并后的数据。如不开辟一个临时的顺序表用于存储合并后的内容,则需在每次插入时移动后续元素,时间复杂度更大。
基本操作:
i. 开辟临时存储空间,数组长度为A表长度+B表长度;
ii. 取A,B中第一个元素a0,b0进行比较:如a0小于b0,将a0放入临时数组,a0变为a1继续比较;如a0小于等于b0,将b0放入临时数组,b0变为b1继续比较。重复操作。
iii. 当A或B表到达数组尾部时结束循环。
iv. 当A未到数组尾部,则将剩余部分放入临时数组;当B未到数组尾部,则将剩余部分放入临时数组。上述二个操作最后只会执行其一。
v. 将临时数组的值通过循环赋值给A表并返回。
具体的算法略。

②单链表:单链表的优点在于插入和删除结点时无需移动元素,因此不用开辟额外的临时存储空间用于存放最终结果,可直接修改其中一个链表以得到结果并返回。
基本操作:
i. 声明指针变量pa指向A的头结点,声明pb指向B的首元结点(这里默认链表有头结点Lnode)。
ii. 比较pa->next->data和pb->data,如pa->next->data>pb->data。那么将pb结点放在pa之后,并删除pb所指结点;如pa->next->data<pb->data,pa = pa->next。
iii. 当pa->next或pb为NULL时结束循环。
iv. 如pb不为空,则把pb剩余部分链接到pa之后,返回。
具体算法见下:
void Merger(Lnode * L, Lnode * T){
 Lnode *p = L;
 Lnode *psave;
 Lnode *q = T->next;
 Lnode *qsave;
 while (p->next && q){
  if (p->next->data < q->data){
   p = p->next;
  }
  else{
   qsave = q->next;
   q->next = p->next;
   p->next = q;
   q = qsave;
   p = p->next;
  }
 }
 if (q) p->next = q;
 return;
}

③不同的合并规则:有时合并规则会有变化,总结后基本有两类。
i. 合并A,B并删除A,B中都存在的元素
基本思想:对于ai, bj不相等的情况操作同上;当ai == bj时则删除ai, bj,ai->ai+1,bj->bj+1。
ii. 合并有序链表A,B且仅保留A,B中都存在的元素
基本思想:对于ai, bj不相等的情况,删除二者中较小者;当ai == bj时则删除bj,ai->ai+1。
④合并要求:
应注意合并要求,比如不允许使用malloc申请存储空间, 不含相同元素。不同要求需要对算法进行一定程度上的修改。
⑤多表合并:
多表合并时类似于两表合并操作,只是每次需要判断三表中ai,bj,ck中最小者进行相应的操作。
这里放上一段算法供参考(将A,B,C表合并为A,仅保留A,B,C中都包含的元素,不允许malloc申请空间,同时释放无用的结点):
Lnode * ChooseSame3(Lnode * L, Lnode * &T, Lnode * &Q){
	if (!L || !L->next || !T || !T->next || !Q || !Q->next) return NULL;
	Lnode * pl = L;
	Lnode * pt = T;
	Lnode * pq = Q;
	Lnode * plsave = NULL;
	Lnode * ptsave = NULL;
	Lnode * pqsave = NULL;
	while (pl->next && pt->next && pq->next){
		if (pl->next->data == pt->next->data && pl->next->data == pq->next->data && pl->next->next->data != pl->next->data){
			pl = pl->next;
			ptsave = pt->next;
			pt->next = ptsave->next;
			free(ptsave);
			ptsave = NULL;
			pqsave = pq->next;
			pq->next = pqsave->next;
			free(pqsave);
			pqsave = NULL;
		}
		else if (pl->next->data == pt->next->data && pl->next->data == pq->next->data){
			plsave = pl->next;
			pl->next = plsave->next;
			free(plsave);
			plsave = NULL;
		}
		else{
			DeleteMinData(pl, pt, pq);
		}
	}
	while (pl->next){
		plsave = pl->next;
		pl->next = plsave->next;
		free(plsave);
	}
	while (pt->next){
		ptsave = pt->next;
		pt->next = ptsave->next;
		free(ptsave);
	}
	while (pq->next){
		pqsave = pq->next;
		pq->next = pqsave->next;
		free(pqsave);
	}
	free(T);
	free(Q);
	T = Q = NULL;
	return L;
}

void DeleteMinData(Lnode * &pl, Lnode * &pt, Lnode * &pq){
	if (pl->next->data <= pt->next->data && pl->next->data <= pq->next->data){
		Lnode * plsave = pl->next;
		pl->next = plsave->next;
		free(plsave);
	}
	else if (pt->next->data <= pl->next->data && pt->next->data <= pq->next->data){
		Lnode * ptsave = pt->next;
		pt->next = ptsave->next;
		free(ptsave);
	}
	else if (pq->next->data <= ql->next->data && pq->next->data <= qt->next->data){
		Lnode *pqsave = pq->next;
		pq->next = pqsave->next;
		free(pqsave);
	}
}
B. 关于链表清空操作
链表清空操作主要就是采用头插法类似的思想。
含有头结点的链表:
Lnode *p = L->next;
while (p){
    L->next = p->next;
    free(p);
    p = L->next;
}
free(L);
L = NULL;//释放头结点


关于逆置操作
逆置操作无需用malloc申请空间,直接从L->next->next处断开,采用头插法逆置。
Lnode * p = L->next->next;
L->next->next = NULL;
Lnode *psave;
while (p){
    psave = p->next;
    p->next = L->next;
    L->next = p;
    p = psave;
}


C. 关于插入和删除操作
如在p的下一节点插入或删除,则按常用方法;
如删除p或在p的位置插入节点,则:
i. 删除:把p的下一节点的数据域拷贝到p节点,然后删除下一节点;
ii. 插入:在p后插入一个节点,把p节点数据域拷贝到后一节点中,再把新的数据赋给p节点。
上述两种方法只是在结果上等同于插入或删除本节点,但实际上也是插入或删除下一节点。
如在p的上一节点出插入或删除。则必须从头搜索或用双向链表。

D. 关于头结点的利弊
这里讨论三种情况。
i. 不含头结点,只有头指针。
这种情况,头指针直接指向第一个结点,最为简单,但在某些操作时需要区别对待,如尾插法插入节点时,需要判断head是否为NULL。
ii. 含头结点,且头结点与普通链表节点相同。
这种情况,头结点仅作一个空节点,带来的便利就是统一操作,尾插法或判断空表时,无需区别对待。
iii. 含头结点,且与普通链表节点不同。
这种头结点一般用于存储链表信息,如链表长度等。但在某些操作时需区别对待,同第一种情况。

E. 补充:
传参时*p和*&p的区别:
前者可以修改p所指节点的内容(包括指针域和数据域,即p->next和p->data都可修改)。
后者除了能够修改p所指节点内容外还能修改p所指的节点地址,因此当采用*&p时,从被调函数返回调用函数时,p所指结点是被调函数中p最终所指向的结点,可能被修改。如不希望修改可采用Lnode * const &p。
由于&为引用传参,可以免去一些时空开销,设计算法时应斟酌考虑。
C# C++ 笔记 变量自定义赋值​# 变量取值用$()​​​​​​clean:多个程序员分发同一程序时,由于不能直接在一个程序上进行功能的开发,所以就有了功能分支的概念。二维数组可以理解为是存储指针的一维数组,里面的每一个指针都指向一个一维数组的首地址存储多个一维数组的数据结构。array 是一个二维数组,它有3行和4列,总共可以存储12个整数。 阅读详情

相关推荐

QT QList介绍及应用

QList是目前最常用的容器类,它存储了给定类型的值的一个列表,而这些值可以通过索引访问。QList使用数组来实现,以确保进行快速的基于索引的访问。 使用QList::append和QList::prepend在列表的两端进行添加项目。 使用QList::insert()在列表的中间插入项目。 实例: #include <QCoreApplication> #include <Q...

qq_30725967的博客 2万+

Qt的通用容器类之一QList<T>类介绍

QList类 QList类是一个提供列表的模板类,要使用这个类,头文件需要导入QList库: #include <QList> 在qmake.pro文件中加入QList类的支持: QT += core QList的派生类有:QByteArrayList, QItemSelection, QQueue还有 QStringList 公共类型: class const_iterator class iterator typedef ConstIterator typedef

mabiao0825的博客 5774

C语言实现单向链表的创建、插入,删除节点,和2个链表合并

VC6.0下 用C语言实现单向链表的创建、插入,删除节点,和2个链表合并等操作

QT之delete

QT delete

weixin_53090658的博客 2299

基于osgEarth的二维态势中时变对象的绘制方法

在态势系统中,卫星、飞机的轨迹、覆盖等的几何数据随时间改变,称之为时变对象。在以OSGEarth实现的二维态势中,如果利用OSGEarth的预定义线、面类型处理这种几何数据的动态改变,则导致效率极具降低。介绍了此问题并给出解决技巧。

eyepeak的博客 2090

如何在项目中集成bpmn-process-designer

文章目录一、bpmn-process-designer是什么?二、使用步骤1.将下面地址的代码下载到本地2.替换dependencies和devDependencies3.拷贝package目录4.在main.js引入代码5.拷贝src5.拷贝App.vue代码注意事项 一、bpmn-process-designer是什么? bpmn-process-designer是一个基于 bpmn.js,Vue 2.x 和 ElementUI 开发的流程设计器(前端部分),支持监听器,扩展属性,表单等配置,可自由扩展

weixin_43550766的博客 9453

list集合中循环删除不要的元素

List<Bean> addList= dataList.getAddList(); for (int i = 0; i < addList.size(); i++) { Bean bean = addDataList.get(i); if (isEmptyById(bean) ) { //循环删除不要的元素,必须i-- ,迭代器需要new2个才能循环出想要的 addList.remove(i--); } } 弄了一下.

qq_21830309的博客 379

Unity游戏开发:从零开始适配Nintendo Switch的完整指南

本文详细介绍了如何使用Unity进行Nintendo Switch游戏开发的完整流程,包括开发环境搭建、Unity工程适配、手柄与硬件特性开发、存储与性能优化等关键步骤。特别强调了Switch SDK的配置、输入系统改造和内存优化技巧,帮助开发者高效完成跨平台适配。

vodka的博客 1067

List中的三种循环遍历及删除操作

1、for循环遍历list public static void main(String[] args) { List list = new ArrayList(); list.add("asdf"); list.add("我多想"); list.add("我多想"); list.add("一少年"); list.add(1); System.out.println(list);

shinian_77的博客 9697

在没有实验数据的情况下,如何高效快速发表高影响因子论文

最新基于Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作方法

glldxh的博客 371

lgv20刷twrp_LG港版v20 root

这是LG港版v20 root,整理了一下有关LG港版v20的官方固件包了,有没有需要的呢,这里把固件包整理一下也是方便大家以后好下载了,因此有一些机友还是不知道在哪里下载官方的rom包,在这里说的固件rom包也就是原版的系统包了,大家可以放心的使用,这些系统包也都是支持线刷的,大家下载下来解压出来根据里面的相关教程来操作就可以了,很简单的,如果你也需要的话就一起来看看吧。软件提示注意!! 此过程会...

weixin_33212263的博客 5387

链表及相关常见问题

链表、常见链表算法问题

CodePanda@GPF的博客 1531

【知识点总结】电机学——原理部分

大家好,由于院校地区存在疫情没法返校,再结合当下形式,去各地旅游放松可能不是一个好的决定,o(╥﹏╥)o,期待已久的旅行就先放一边吧,但也不能闲着,既然无事,那不如继续我的总结,本次总结的内容是电机学,自九推以后我越来越明白电机学的重要性……呜呜呜~~实在太重要了,几乎所有与专业复试有关的题目都会涉及电机学,而它又比较抽象,容易使人浅尝辄止,只能理解一些表面的东西。为此自九推之后,我深刻领悟自身不足,决定对电机学发起依次猛攻,势必要将其彻底拿下,这这只是我的粗略总结,若有空闲,我将不断完善它。

weixin_51130221的博客 1万+

不带头节点的单链表

.h# pragma once # include&lt;stdio.h&gt; # include&lt;stdlib.h&gt; # include&lt;string.h&gt; # include&lt;assert.h&gt; typedef int DataType; typedef struct Node { struct Node* _pNext; DataType _da...

xuruhua的博客 2791

ABA分析方法 — 软硬件开发必备的一种分析问题绝佳套路

可能你从很多地方听过这个名词,无论是在软件开发还是硬件领域(比较典型的领域:汽车、消费电子、医疗等行业),ABA验证都是一种快速分析故障的一个方法,第一次听到这个词,当时是不是一脸懵逼,本文就深度带你了解下ABA的分析方法。简要概述就是:怀疑A模块导致系统故障,将B模块替换A模块,故障消失,再将A模块替换回来,故障复现,则说明A模块是导致系统故障的原因其实,ABA分析问题,可能很多人在工作中都或多或少用过这个方法,只是没有这个概念,说明白了就是控制变量和对比验证,没什么高大上的东西。

Eureka1024的博客 7322

RK3568平台(camera篇)点亮imx586摄像头

mipi摄像头硬件确认点:1.供电:5V,2.8V,1.2V,1.8V,reset脚(硬拉3.3,上电的时候从低到高),pwron脚外接3.3V。2,时钟:MCLKOUT是24兆时钟。3.4组差分mipi线。mipi的data线的波形为方波。

weixin_49303682的博客 7257

C++单链表的模板类实现(含文件输入输出)

#include <iostream> #include <fstream> #include <typeinfo> #include <iomanip> using namespace::std; template <class T> struct LinkNode {//链表结点定义 T data; LinkNode<T>* link; LinkNode(LinkNode<T>* ptr = NULL) {.

m0_53917001的博客 2105

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++--list

/构造int类型的空容器//构造含有10个2的int类型容器//拷贝构造int类型的lt2容器的复制品//构造string对象某段区间的复制品//构造数组某段区间的复制品。

weixin_66905164的博客 473

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Redis源码阅读(三)adlist.h 和adlist.c

redis源码阅读,adlist

Orange_pa的博客 358

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

[c++] 初阶 手把手教你手搓stl中list容器<list介绍篇>

介绍list的基本使用

2301_79949691的博客 210

分块算法:从暴力到优雅的区间操作优化方案

在算法与数据结构中,处理大规模数据的区间操作是一个常见挑战。其核心原理是通过将数据分割为多个块,在块级别维护聚合信息(如区间和)和懒标记,从而平衡操作效率。这种设计在工程上实现了时间复杂度从O(N)到O(√N)的优化,显著提升了处理效率。技术价值在于它提供了一种介于朴素暴力与复杂数据结构(如线段树)之间的折中方案,代码实现更简单,调试更容易。应用场景广泛,包括数据库索引优化、文件系统设计以及需要快速实现数据区间查询与修改的算法题目。本文深入探讨了分块算法的通用模型,详细解析了其处理区间加法与求和的实现,并分

weixin_30697239的博客 488

【SystemVerilog验证】数据类型

SystemVerilog相比Verilog在数据结构方面有显著改进,主要包括: 增强的数据类型 引入双状态数据类型(bit, byte等)提升性能并减少内存消耗 新增logic类型解决reg/wire选择困惑 支持字符串(string)处理 灵活的数组类型 动态数组:运行时确定大小 队列:结合数组和链表优点,支持高效增删 关联数组:稀疏存储,支持复杂索引 合并数组:紧凑存储,支持多种访问方式 结构化数据类型 结构体(struct)组织相关数据 联合体(union)实现多格式数据访问 枚举类型(enum)增

wuyufei_sun的博客 439

python的数据结构

'''容器可以进行增删改查''' ''' 列表:[],可变、有序可重复、类型可不一样,链表结构 列表的操作: 增:append(元素),extend(iterable):可添加多个元素,insert()在指定位置添加元素 删:remove(元素),pop(index)默认删除最后一个,clear()清空 改:list[index]=新元素 查:index(元素),...

ryuhfxz的博客 192

力扣100题解(1)

的输入如下(你设计的程序。

Yuking_Go的博客 163

每周技术面试高频题汇总:大厂面试官到底在考什么?完整实战指南

大家好,又到了每周的面试复盘时间。。现在的面试官更喜欢把你扔进一个具体的“场景”里,看你怎么思考、怎么权衡(Trade-off)。基于过去一周 优快云、掘金、LeetCode 等社区的热议内容,我为大家精选了,涵盖算法、系统设计、数据库和网络四大领域。咱们不整那些虚的,直接上干货,看看这些题目背后的考察点和解题思路。

热爱技术与前沿创新,深耕科技领域,在科创中精进自我;探索技术乐趣,分享技术干货与成长心得,以技术为伴,热爱生活,在科创与生活中双向成长。 482

STL语句

STL从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),容器和算法通过迭代器可以进行无缝地连接。几乎所有的代码都采 用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。 STL的一个重要特点是数据结构和算法的分离。 1、容器:用来管理一组数据,下面介绍几种常用的容器 1)string:string

yizhe0731的博客 3204
上一篇: const、volatile和restrict的作用和用法总结
下一篇: 二叉树与森林的转换
coderhuhy
博客等级 码龄12年 24粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值