原创公众号:bigsai 如有帮助欢迎一键三联
文章已收录在 全网都在关注的数据结构与算法学习仓库 欢迎star

前言

在前面,我写过一篇Java的深浅拷贝,那是基于对象的拷贝,但放眼数据结构与算法中,你有考虑过怎么拷贝一个图吗?(无向图)

在此之前,你需要对一些概念搞清楚:什么是深拷贝、浅拷贝?

浅拷贝:如果拷贝的是引用类型(非基本类型),就只会拷贝一层(嵌套的对象不会被拷贝),如果原对象发生改变,那么拷贝对象也会发生改变。

深拷贝:深拷贝的话会拷贝多层,嵌套的对象也会被拷贝出来,相当于开辟一个新的内存地址用于存放拷贝的对象。

用通俗一点(可能不完全确切)的话解释,浅拷贝就像你的双胞胎兄弟一样,你们父母亲人都是一样的;而深拷贝就像另一个平行的时空,那里有另一个你的一切。

既然搞懂了深浅拷贝以及其区别,我们再看看图,图一般用来表示节点和节点之间的关系,常分为有向图和无向图,在这里我们以无向图(一旦连接即双向)为主题。

我们对图的表示一般有邻接矩阵和邻接表,邻接矩阵的话比较直观的表示一个图的连通性,操作维护更简单,在Java中一般使用二维数组表示邻接矩阵,数组中的值可以表示两个节点的权值。


使用邻接矩阵虽然简单但是有个比较差的就是浪费较多内存空间,所以很多情况还是使用邻接表来表示一个图,邻接表一般是数组+链表的这么一个组合。但是也有一些特殊情况各个节点比较独立的不用数组联立。

问题分析

如果这个图使用邻接表表示,给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆),这个问题是力扣131克隆图原题。

图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node])。

class Node {public int val;public List<Node> neighbors;
}

给一个节点的引用,怎么克隆这个图呢?

如果只有这一个节点,那么克隆这个节点就好。如果这个节点只有一层邻居,那克隆这个邻居的列表(克隆List集合)即可。

但事实是这个节点可能有多层邻居,并且邻居之间可能存在着复杂联系。

克隆整个图,所以图的每一个节点都要被克隆的,我们需要使用图论的搜索算法来枚举所有节点,并且在遍历的过程中我们需要想办法将节点之间的关系也克隆下来。遍历的方法可以使用dfs或者bfs,这里使用bfs来实现。

凡是遇到苦难的时候我们模拟一下这个克隆的过程即可,通过下面这张图可以大概了解克隆图的过程中,最大的问题是要避免创建重复节点。即有的节点一旦被创建它的引用可能在后面会被用到的。

那我们该如何解决这个问题呢?怎么样能够快速找到对应节点的引用?

这里最好的方法是使用HashMap<Node,Node>,其中key保存的是被克隆图中的节点,而value是在克隆图中所对应的节点,这样在克隆新图的过程中,我们遍历被克隆图中节点邻居的时候,就可以用哈希判断这个节点对应的value是否存在(即这个节点在克隆图中是否存在)。

  • 如果存在那么直接使用HashMap找到对应节点放入克隆图中新创建的List中。
  • 不过不存在说明这个节点第一次遇到,克隆这个节点,先放到hashMap中与被克隆节点对应,然后放入克隆图中新创建的List中。

这个流程其中大概是这样的:

有了上面的分析,想必你对这个问题的解决已经有了思路和想法,下面就提供一下代码实现。

/*
// Definition for a Node.
class Node {public int val;public List<Node> neighbors;public Node() {val = 0;neighbors = new ArrayList<Node>();}public Node(int _val) {val = _val;neighbors = new ArrayList<Node>();}public Node(int _val, ArrayList<Node> _neighbors) {val = _val;neighbors = _neighbors;}
}
*/class Solution {public Node cloneGraph(Node node) {if(node==null)return null;Map<Node, Node>map=new HashMap<Node, Node>();//节点映射克隆的节点Queue<Node>oldqueue=new ArrayDeque<Node>();//bfs队列oldqueue.add(node);Node value=new Node(node.val);//先将返回的节点 创建、映射map.put(node, value);while (!oldqueue.isEmpty()) {Node oldnode=oldqueue.poll();Node newnode=map.get(oldnode);//找到这个节点对应克隆的映射(一定存在)List<Node>list=oldnode.neighbors;//邻居List<Node>listnew=new ArrayList<Node>();//克隆邻居for(Node team:list){if(map.containsKey(team)){listnew.add(map.get(team));//点以前已经遇到,直接添加到邻居列表}else {//这个邻居第一次碰到,需要创建新节点赋予值Node no=new Node(team.val);map.put(team, no);//映射listnew.add(no);oldqueue.add(team);//这个点第一次遇到,要将它放到队列中进行bfs搜索}}newnode.neighbors=listnew;//将节点的邻居指向list}return value;}
}

本篇内容到这里就结束啦,还希望你能一键三联支持一下!
新人求关注!关注后欢迎加入力扣打卡群(备注力扣 csdn即可),持续产出肝货!

深拷贝一个对象会了,怎么深拷贝一个图?相关推荐

  1. python深拷贝一个对象_Python中的深拷贝和浅拷贝以及存在的问题

    在讨论浅拷贝和深拷贝之前,首先要了解python中两个对象比较==和is==操作符进行的是对象的值判断,比较两个对象的值是否相等. is操作符进行的是对象的身份标识的判断,比较两个对象的内存地址是否相 ...

  2. python深拷贝一个对象_Python对象的深拷贝和浅拷贝详解

    本文内容是在<Python核心编程2>上看到的,感觉很有用便写出来,给大家参考参考! 浅拷贝 首先我们使用两种方式来拷贝对象,一种是切片,另外一种是工厂方法.然后使用id函数来看看它们的标 ...

  3. 刚学会深拷贝一个对象,学妹却问我怎么深拷贝一个图

    前言 在前面,我写过一篇Java的深浅拷贝,那是基于对象的拷贝,但放眼数据结构与算法中,你有考虑过怎么拷贝一个图吗?(无向图) 在此之前,你需要对一些概念搞清楚:什么是深拷贝.浅拷贝? 浅拷贝:如果拷 ...

  4. Java对象深拷贝详解(List深拷贝)

    1.Java中拷贝的概念 在Java语言中,拷贝一个对象时,有浅拷贝与深拷贝两种 浅拷贝:只拷贝源对象的地址,所以新对象与老对象共用一个地址,当该地址变化时,两个对象也会随之改变. 深拷贝:拷贝对象的 ...

  5. clone是深拷贝还是浅拷贝_go-clone:深拷贝 Go 数据结构

    继续闲来写写码,这次来介绍一下半年多以前写的一个库,最近工作中发现真的有用,还是值得推荐一下的. 背景 这个库是 github.com/huandu/go-clone,主要用途是对任意的 Go 结构进 ...

  6. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递

    问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  (下面内存图解:栈内存是先进后出的,画错了 ) 答:是值传递.Java ...

  7. 将matlab中多幅图合成为一幅图,MATLAB画图之多个图以子图的形式合为一个图

    解决问题:已经画好了多个figure,在不重复添加画图程序时,将多个图合为一个图. 通常我们会将各个图单独画出来看效果,但是写文章过程中,经常为了排版等问题,需要将几个图分别以子图的形式合为一个图,这 ...

  8. 详解深拷贝和浅拷贝以及如何深拷贝

    深拷贝和浅拷贝 一.如何区分深拷贝和浅拷贝 二.举例加深理解深拷贝和浅拷贝 三.图文理解 四.哪些方法是浅拷贝,如何进行深拷贝 一.如何区分深拷贝和浅拷贝 内在的区别:浅拷贝就是简单的把指向别人的值的 ...

  9. 什么是深拷贝,为什么要进行深拷贝,如何进行深拷贝

    标题直接引入话题,接下来就说说,什么是浅拷贝,和深拷贝吧 1,浅拷贝和深拷贝 2,浅拷贝和深拷贝的区别 浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用 深拷贝 ...

最新文章

  1. mybatis配置文件解析
  2. 为什么选择angular?-学习笔记
  3. shell 脚本字符串 分割或截取
  4. ajax鼠标滚动请求 或 手机往下拉请求
  5. html 高德地图坐标,点标记-调起高德地图-示例中心-JS API 示例 | 高德地图API
  6. spring连接mysql出现问题_spring+hibernate连接mysql问题啊
  7. win98 支持html5,对“让sbpci 128在win98下支持WDM”的补充
  8. 豆瓣评分9.3!运动规划圣经,自动驾驶学习必备书!
  9. 【软件工程】软件工程需求分析——面向对象分析
  10. Excel表的标题栏锁定
  11. 11尺寸长宽 iphone_2019新发布iPhone 11、iPhone 11 Pro、iPhone 11 Pro Max尺寸规格对比
  12. C++11新特性 - 侯捷
  13. Java程序员转行可以做什么?程序员
  14. OA项目实战学习(3)——实现岗位管理增删改查
  15. 开学数码装备分享,大学新生必备数码好物
  16. 没有植入的内容就是TM在逗我
  17. NodeJs 的fs模块
  18. Polyhedral Compilation及ISL学习资料
  19. 关于计算机软件技术基础知识,《计算机软件技术基础》知识要点.doc
  20. xbox game bar无法打开/安装怎么办?

热门文章

  1. python 语言教程(2)基础语法之标识符
  2. 区块链BaaS云服务(16)天德链TDBC“交易数据”
  3. Linux GCC用法
  4. SEO -- 搜索引擎优化
  5. Vue+ElemtUI中对el-dialog弹出框宽度调整方法
  6. 密码学基础知识(十)查缺补漏(缺)
  7. 密码学基础知识(五)序列密码
  8. Fabric--CA 应用与配置
  9. (71)APC队列,KAPC结构,分析 TerminateThread ,QueueUserApc
  10. const 和指针赋值