C语言之复杂链表的复制详解

发布时间 - 2026-01-11 02:09:49    点击率:

什么是复杂链表?

复杂链表指的是一个链表有若干个结点,每个结点有一个数据域用于存放数据,还有两个指针域,其中一个指向下一个节点,还有一个随机指向当前复杂链表中的任意一个节点或者是一个空结点。今天我们要实现的就是对这样一个复杂链表复制产生一个新的复杂链表。

复杂链表的数据结构如下:

typedef int DataType; //数据域的类型
//复杂链表的数据结构
typedef struct ComplexNode

{

DataType _data ;   // 数据
struct ComplexNode * _next;  // 指向下个节点的指针
struct ComplexNode * _random; // 指向随机节点(可以是链表中的任意节点 or 空)

}ComplexNode; 

上图就是一个复杂链表的例子,那么我们应该如何实现复杂链表的复制呢?

1、首先我们应该根据已有的复杂链表创建一条新的复杂链表,但是这个新的复杂链表的所有的结点的random指针都指向空,这样是很好实现的,相当于我们创建了一条简单的单链表(newlist),我们要复制的链表不妨称之为oldlist。

2、接下来我们应该把新创建的这条复杂链表(newlist)与已有的复杂链表(oldlist)合并成如下的形式:

在这种情况下我们已经把两条复杂链表合并成了一条链表(称之为linklist),通过对这条链表(linklist)的观察,我们可以发现合并的链表(linklist)中属于newlist的结点pnew的上一个结点pold(属于oldlist的结点)的random指针所指向的结点的next指针就应该是pnew结点的randow指针所指向的结点。

这样我们让pold和pnew指针一直往后走最后就可以实现对所有属于新创建的复杂链表(newlist)的random指针指向相应的结点的操作。构成的复杂链表如下图

在完成以上的步骤之后我们所要做的工作就很简单了,我们只要把这一条链表linklist分开成我们的newlist链表和oldlist链表就可以了。

这样我们就完美的完成了复杂链表的复制工作下面就是具体实现的代码:

头文件complexnode.h:

#ifndef __COMPLEX__NODE__H__
#define __COMPLEX__NODE__H__
//包含头文件
#include <stdio.h>
#include<stdlib.h>
#include <assert.h>

typedef int DataType; //数据域的类型
//复杂链表的数据结构
typedef struct ComplexNode

{
DataType _data ;    // 数据
struct ComplexNode * _next;  // 指向下个节点的指针
struct ComplexNode * _random; // 指向随机节点(可以是链表中的任意节点 or 空)
}ComplexNode;

 

//创建一个复杂链表的结点
ComplexNode * BuyComplexNode(DataType x);
//打印复杂的单链表
void Display(const ComplexNode * cplist);
//复杂链表的复制
ComplexNode * CopyComplexNode(ComplexNode * cplist);

 

#endif//__COMPLEX__NODE__H__

具体功能实现complexnode.c

#include "complexnode.h"

 

//创建一个复杂链表的结点

ComplexNode * BuyComplexNode(DataType x)
{
ComplexNode *cnode = (ComplexNode *)malloc(sizeof(ComplexNode));
if(cnode == NULL)//创建失败
{

perror("BuyComplexNode()::malloc");
return NULL;

}

//创建成功
cnode->_data = x;
cnode->_next = NULL;
cnode->_random = NULL;
return cnode;

} 

//打印复杂的单链表

void Display(const ComplexNode * cplist)

{

ComplexNode *pnode = cplist;
while (pnode)
{
printf("%d::%d -->",pnode->_data,pnode->_random->_data);
pnode = pnode->_next;

}

printf("over\n");

}

//复杂链表的复制
ComplexNode * CopyComplexNode(ComplexNode * cplist)

{
ComplexNode * pold = NULL;
ComplexNode * pnew = NULL;
ComplexNode * newlist = NULL;//指向新的复杂链表的头结点的指针
pold = cplist;

//创建一条新的复杂链表

while(pold != NULL)

{
ComplexNode * new_node = BuyComplexNode(pold->_data);
if(newlist == NULL)//当新的复杂链表中没有结点时
{
newlist = new_node;

}

else//当新的复杂链表有结点时

{
ComplexNode * node = newlist;
while(node->_next != NULL)//找到最后一个结点
{
node = node->_next;
}
node->_next = new_node;//插入新的结点
}
pold = pold->_next;

 

}//创建新的复杂链表结束

 

//合并两条复杂链表
pold = cplist;
pnew = newlist;
while (pold)

{

ComplexNode * curold = NULL;
ComplexNode * curnew = NULL;
curold = pold->_next;
curnew = pnew->_next;
if(pold->_next == NULL)

{

pold->_next = pnew;
pold = curold;
pnew = curnew;
break;

}

pold->_next = pnew;
pnew->_next = curold;
pold = curold;
pnew = curnew;
}//合并两条复杂链表结束

 

//让新创建的那条复杂链表上的所有结点的random指针指向相应的结点
pold = cplist;
pnew = newlist;
while (pnew)

{

pnew->_random = pold->_random->_next;

pold = pnew->_next;
if(pold == NULL)//这是pnew的_next指针已经指向空

{

break;

}

pnew = pold->_next;

}//结束

 

//分离合并后的复杂链表

pold = cplist;
pnew = newlist;
while (pold)

{

ComplexNode * curold = NULL;
ComplexNode * curnew = NULL;
if(pnew->_next == NULL)//已经分离完成

{

pold->_next = NULL;
pnew->_next = NULL;
break;

 

}

curold = pold->_next->_next;
curnew = pnew->_next->_next;

 

pold->_next = curold;
pnew->_next = curnew;
pold = curold;
pnew = curnew;

}//分离合并的复杂链表结束

 

return newlist;

}

测试代码test.c:

#include "complexnode.h"

//
//复杂链表的复制。?个链表的每个节点,有?个指向next指针指向下?个节
//点,还有?个random指针指向这个链表中的?个随机节点或者NULL,现在要
//求实现复制这个链表,返回复制后的新链表。
//ps: 复杂链表的结构
 

void test()

{

ComplexNode * cplist;
ComplexNode * copylist;
ComplexNode * node1;
ComplexNode * node2;
ComplexNode * node3;
ComplexNode * node4;
cplist = BuyComplexNode(1);
node1 = BuyComplexNode(2);
node2 = BuyComplexNode(3);
node3 = BuyComplexNode(4);
node4 = BuyComplexNode(5);
cplist->_next = node1;
node1->_next = node2;
node2->_next = node3;
node3->_next = node4;
cplist->_random = node3;
node1->_random = node4;
node2->_random = cplist;
node3->_random = node1;
node4->_random = node2;
Display(cplist);
copylist = CopyComplexNode(cplist);
Display(copylist);


}
int main()
{
test();
return 0;

}

程序的运行结果如下图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# C语言  # 链表  # C语言之复杂链表的复制方法(图示详解)  # C语言数据结构之复杂链表的拷贝  # C语言复杂链表的复制实例详解  # 数据结构  # 两条  # 我们应该  # 这条  # 下个  # 创建一个  # 如下图  # 就可以  # 称之为  # 是一个  # 这是  # 头文件  # 这一  # 很好  # 成了  # 要把  # 我们可以  # 很简单  # 这样一个 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 韩国服务器如何优化跨境访问实现高效连接?  JavaScript Ajax实现异步通信  laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法  Laravel如何实现数据库事务?(DB Facade示例)  桂林网站制作公司有哪些,桂林马拉松怎么报名?  ,怎么在广州志愿者网站注册?  微信小程序 canvas开发实例及注意事项  如何在阿里云域名上完成建站全流程?  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】  郑州企业网站制作公司,郑州招聘网站有哪些?  Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出  如何用虚拟主机快速搭建网站?详细步骤解析  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践  高端网站建设与定制开发一站式解决方案 中企动力  制作公司内部网站有哪些,内网如何建网站?  如何快速查询网址的建站时间与历史轨迹?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  如何快速查询域名建站关键信息?  如何快速搭建支持数据库操作的智能建站平台?  如何快速搭建个人网站并优化SEO?  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】  VIVO手机上del键无效OnKeyListener不响应的原因及解决方法  Python面向对象测试方法_mock解析【教程】  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  浅述节点的创建及常见功能的实现  Laravel如何处理表单验证?(Requests代码示例)  Laravel用户密码怎么加密_Laravel Hash门面使用教程  网站制作企业,网站的banner和导航栏是指什么?  如何在阿里云服务器自主搭建网站?  活动邀请函制作网站有哪些,活动邀请函文案?  LinuxCD持续部署教程_自动发布与回滚机制  夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化  焦点电影公司作品,电影焦点结局是什么?  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  HTML 中如何正确使用模板变量为元素的 name 属性赋值  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  Laravel的.env文件有什么用_Laravel环境变量配置与管理详解  BootStrap整体框架之基础布局组件  如何在服务器上三步完成建站并提升流量?  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  Android使用GridView实现日历的简单功能  nginx修改上传文件大小限制的方法  北京网站制作的公司有哪些,北京白云观官方网站?