移除两个双向链表中的重复元素,每个链表中的元素不重复

移除两个双向链表中的重复元素,每个链表中的元素不重复,请给出算法。

ans: 该问题比单向链表要更加复杂一些,必须考虑并更新前向节点的指向情况,具体编码中存在一些难度,加上链表调试相对不容易,因此难度系数略高。

主要思路为:

  • 为每个链表添加哨兵节点,哨兵节点方便操作,因为头节点可能为重复元素
  • 访问链表A的首元素,和链表B的元素依次做对比
    • 当对比相等时,
      • 移除B的当前元素,更新B的指向
      • 移除A的当前元素,更新A的指向
      • break B
    • 当对比不相等时,
      • 链表B指针依次后移,直到为空
  • 当链表B的指针指向为空时,更新链表A的指针指向,继续对比,直到链表A为空
  • 打印出链表元素,因为是双向链表,必须两个方向打印,方能确保正确。
  • 代码如下,main中运行testList即可
typedef struct Node { //双链节点 定义int data;struct Node *prev, *next;
} DList;void PrintList(DList *head) { // 打印链表,DList *cur = head;while(cur != NULL) { // 正向打印printf("%d ", cur->data);cur = cur->next;if(cur) {printf(" -> ");}}printf(" || ");cur = head;while(cur->next != NULL) { // 寻找尾巴节点cur = cur->next;}while(cur != NULL) { // 反向打印printf("%d", cur->data);cur = cur->prev;if(cur) {printf(" -> ");}}
}void delSameDataNodes(DList **pHead1, DList **pHead2) { // 因会修改head 节点指向,所以必须使用二级指针if(*pHead1 == NULL || *pHead2 == NULL) {return;}DList* dummy1 = (DList *) malloc(sizeof(DList));  // 哨兵节点DList* dummy2 = (DList *) malloc(sizeof(DList));dummy1->next = *pHead1;  // 哨兵节点添加到头节点前面dummy2->next = *pHead2;dummy1->prev = NULL;  // 哨兵节点初始化dummy2->prev = NULL;dummy1->data = 0;dummy2->data = 0;DList* pc1 = *pHead1; // 为每个链表定义前节点,当前节点,后续节点指针DList* pf1 = dummy1;DList* pn1 = pc1->next;DList* pc2 = *pHead2;DList* pf2 = dummy2;DList* pn2 = pc2->next;int dup = 0; // 是否重复指示标志位while(pc1 != NULL) { // 链表A开始循环,逐一元素访问pf2 = dummy2; // 每当链表A访问新元素时, 链表B的3个指针必须从链表头重新开始指向,因pHead2有可能被移除,因此只能用哨兵节点pc2 = pf2->next;pn2 = pc2->next;while(pc2 != NULL) {if(pc1->data != pc2->data) {  // 两个链表元素不等时,链表2继续向后检索,知道链表末端,注意更新3个指针pf2 = pc2;pc2 = pn2;pn2 = (pn2 == NULL)?NULL:pn2->next; // 如果pn2 为空时,不能对其赋值} else {  // 两个链表元素相等时 ,需要设置标志位,跳过当前节点 pc2dup = 1;  // 设置标志位if(pn2) { // 如果pn2 非空时,跳过当前节点,并更新指针,因跳出当前循环,所以此处pc2可以不用设置pf2->next = pn2;pn2->prev = pf2;} else {pf2->next = NULL;}break;}}if(dup == 1) {dup = 0;if(pn1) {pf1->next = pn1;pn1->prev = pf1;pc1 = pn1;  // 此处pc1 必须设置pn1 = pn1->next;} else {pf1->next = NULL;}} else {pf1=pc1;pc1=pn1;pn1 = (pn1 == NULL)?NULL:pn1->next;}}*pHead1 = dummy1->next;*pHead2 = dummy2->next;(*pHead1)->prev = NULL;(*pHead2)->prev = NULL;free(dummy1);dummy1 = NULL;free(dummy2);dummy2 = NULL;
}void add2Tail(DList **head, int data) {DList *node = (DList*) malloc(sizeof(DList));node->data = data;node->next = NULL;node->prev = NULL;if(*head == NULL) {*head = node;} else {DList *cur =*head;while(cur->next!=NULL) {cur = cur->next;}cur->next = node;node->prev = cur;}
}void testList(void){DList *head1 = NULL;DList *head2 = NULL;add2Tail(&head1, 1);add2Tail(&head1, 2);add2Tail(&head1, 3);add2Tail(&head1, 4);add2Tail(&head1, 8);add2Tail(&head1, 9);printf("original list 1: ");PrintList(head1);printf("\n");add2Tail(&head2, 1);add2Tail(&head2, 2);add2Tail(&head2, 4);add2Tail(&head2, 5);add2Tail(&head2, 6);add2Tail(&head2, 7);add2Tail(&head2, 9);printf("original list 2: ");PrintList(head2);printf("\n---------------\n");delSameDataNodes(&head1, &head2);printf("remove duplicate list1: ");PrintList(head1);printf("\n");printf("remove duplicate list2: ");PrintList(head2);printf("\n");
}

结果显示如图:
在这里插入图片描述

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

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

相关文章

C++标准学习--decltype

decltype / auto 是具有类型推导功能的 类型 描述/占位 符 decltype: 获取对象或表达式的类型auto: 类型自动推导 decltype 可以获取变量类型, (并不同于python的type,但python能打印出type获取的名称, C通过typeid实现&#xff…

HTML---JQurey的基本使用

文章目录 目录 文章目录 本章目标 一.JQuery下载安装 二.JQuery概述 JQuery的作用 JQuery的优势 JQUery示例 三.JQuery基础 语法结构 JQuery常用内置函数 总结 本章目标 (1)能够搭建jQuery开发环境 (2)使用ready( )方法加…

机器人技能学习-robosuite-0-入门介绍

文章目录 前言模块介绍实战案例1:从 demo 中创建自己的 env案例2:更换属于自己的物体 前言 资料太少、资料太少、资料太少,重要的事说三边,想根据自己实际场景自定义下机器人,结果发现无路可走,鉴于缺少参…

MathType绝对是我数学编辑的首选工具!

去年,微软曾说,要去掉Office里的公式编辑器,建议用户使用MathType编辑公式。目前Office用户可以到微软官网安装MathType的插件,现在免费使用,以后要收费。Word里安装这个插件以后,就会出现MathType的菜单。…

Kafka与RabbitMQ的区别

消息队列介绍 消息队列(Message Queue)是一种在分布式系统中进行异步通信的机制。它允许一个或多个生产者在发送消息时暂时将消息存储在队列中,然后由一个或多个消费者按顺序读取并处理这些消息。 消息队列具有以下特点: 异步通…

数模学习day11-系统聚类法

本文参考辽宁石油化工大学于晶贤教授的演示文档聚类分析之系统聚类法及其SPSS实现。 目录 1.样品与样品间的距离 2.指标和指标间的“距离” 相关系数 夹角余弦 3.类与类间的距离 (1)类间距离 (2)类间距离定义方式 1.最短…

二阶贝塞尔曲线生成弧线

概述 本文分享一个二阶贝塞尔曲线曲线生成弧线的算法。 效果 实现 1. 封装方法 class ArcLine {constructor(from, to, num 100) {this.from from;this.to to;this.num num;return this.getPointList();}getPointList() {const { from, to } thisconst ctrlPoint thi…

我开源了一个 Go 学习仓库

前言 大家好,这里是白泽,我是21年8月接触的 Go 语言,学习 Go 也正好两年半,我决定重启我之前未完成的计划,继续阅读《The Go Programing Language》,一年多前我更新至第五章讲解的时候,工作的忙…

阅读笔记lv.1

阅读笔记 sql中各种 count结论不同存储引擎计算方式区别count() 类型 责任链模式常见场景例子(闯关游戏) sql中各种 count 结论 innodb count(*) ≈ count(1) > count(主键id) > count(普通索引列) > count(未加索引列)myisam 有专门字段记录…

pytorch学习笔记(十)

一、损失函数 举个例子 比如说根据Loss提供的信息知道,解答题太弱了,需要多训练训练这个模块。 Loss作用:1.算实际输出和目标之间的差距 2.为我们更新输出提供一定的依据(反向传播) 看官方文档 每个输入输出相减取…

手把手教你学会接口自动化系列九-封装调用之后的代码展示

接上篇: 手把手教你学会接口自动化系列八-将url写在配置文件中,封装调用-CSDN博客 下来把之前写的demo开始改造,将所有的url = http://192.168.0.134:8081的部分,替代了 如下: demo的改造 # !/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2023/05# @Author …

S1-06 消息队列

消息队列 消息队列是一种在多任务操作系统中广泛使用的通信机制。它可以用于不同任务之间的消息传递,从而实现数据共享和协调处理任务之间的顺序。 消息队列通常具有以下基本特点: 消息队列的大小有限:消息队列被设计为一种缓冲区&#xff…

【软件测试】路径覆盖

题目要求: a) 流程图如下: b) Consider test cases ti (n 3) and t2 ( n 5). Although these tour the same prime paths in printPrime(), they dont necessarily find the same faults. Design a simple fault that t2 would be more lik…

Legion R7000 2021(82JW)原装出厂Win10/WIN11系统预装OEM系统镜像

LENOVO联想拯救者R7000 2021款(82JW)笔记本电脑原厂Windows10/11系统 链接:https://pan.baidu.com/s/1m_Ql5qu6tnw62PbpvXB0hQ?pwd6ek4 提取码:6ek4 原装出厂系统自带所有驱动、出厂主题壁纸、系统属性专属联机支持标志、系统属性专属联想的LOGO标…

js:使用canvas画一个半圆

背景 需求需要画一个半圆&#xff0c;或者多半圆&#xff0c;其实一下子就能想到 canvas 中的圆弧&#xff0c;核心使用 context.arc context.arc(x,y,r,sAngle,eAngle,counterclockwise)接下来我们看看示例 例一 <!DOCTYPE html> <html lang"en"> &…

C++八股学习心得.8

1.const知道吗&#xff1f;解释其作用 const 修饰类的成员变量&#xff0c;表示成员常量&#xff0c;不能被修改。 const修饰函数承诺在本函数内部不会修改类内的数据成员&#xff0c;不会调用其它非 const 成员函数。 如果 const 构成函数重载&#xff0c;const 对象只能调…

Canopen学习笔记——sync同步报文增加数据域(同步计数器)

1.Canfestival同步报文sync的设置 在OD表中的配置如下&#xff1a; 如果0x1006索引的同步报文循环周期时间设置为0则禁用同步报文&#xff0c;这里要注意的就是&#xff0c;上面第一张图也提到了&#xff0c;时间单位是us。第二张图&#xff0c;我的0x1006就设置为0xF4240,也就…

Docker与微服务实战(高级篇)- 【下】

Docker与微服务实战&#xff08;高级篇&#xff09;- 【下】 八、Docker轻量级可视化工具Portainer8.1.可视化工具Portainer简介8.2.安装Portainer8.2.1.官网8.2.2.docker命令安装8.2.2.1.搜索portainer镜像8.2.2.2.拉取portainer镜像8.2.2.3.启动portainer容器 8.2.3.第一次登…

高通平台开发系列讲解(USB篇)adb function代码分析

文章目录 一、FFS相关动态打印二、代码入口三、ffs_alloc_inst四、ep0、ep1&ep2的注册五、读写过程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本文主要介绍高通平台USB adb function代码f_fs.c。 一、FFS相关动态打印 目录:msm-4.14/drivers/usb/gadget/fun…

Git新手?这篇文章带你飞!基础操作一网打尽!

推荐阅读 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;一&#xff09; 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;二&#xff09; 文章目录 推荐阅读Git初识Git啥是版本控制系统&#xff1f;&#xff1f;集中式VS分布式 git使用…