java用十字链表实现无向图_实验四:图的实现与应用

20162317袁逸灏 实验四:图的实现与应用

实验内容

邻接矩阵

十字链表

实现无向图中的

添加结点

删除结点

添加边

删除边

size()

isEmpty()

广度优先迭代器

深度优先迭代器

方法

实验要求

实验1:用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器

给出伪代码,产品代码,测试代码(不少于5条测试)

上方提交代码链接

附件提交测试截图

实验2:用十字链表实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器

给出伪代码,产品代码,测试代码(不少于5条测试)

上方提交代码链接

附件提交测试截图

实验3:实现PP19.9

给出伪代码,产品代码,测试代码(不少于5条测试)

上方提交代码链接

附件提交测试截图

实验过程

实验1

邻接矩阵是存储图的一种方式,它通过一个矩阵来表示哪些点之间有联系。主要有两种表达方式。

方式1:用0和1来表示

4348d09c42ed8cb6d1648413fdea1257.png

在矩阵种,1代表相连接,0代表不相连。

方式2:用权值来表示

4742511cc1dd2d8e4542bed7f49108f4.png

当两点相连的时候,矩阵的位置为权值;若两点不为邻接点,矩阵的位置为无穷大。

邻接矩阵的特点:

无向图的邻接矩阵对称,可压缩存储;

无向图中顶点 vi 的度是邻接矩阵中第 i 行 1 的个数。

有向图邻接矩阵不一定对称;

有向图中顶点 vi 的出度是邻接矩阵中第 i 行 1 的个数。 顶点 vi 的入度是邻接矩阵中第 i 列 1 的个数。

邻接矩阵的实现:

初步实现

需要一个边的类,类中要有三个变量,两个是顶点变量,一个是边的权重变量。

要实现保存点的功能,鉴于后面有添加点的方法,因此最好实例化一个List来保存点,这样可以使长度不受限制。

实现保存边的功能,鉴于该实验的要求是使用邻接矩阵来实现图的储存。因此,在保存边这一方面,需要用一个二维数组来保存,该数组大小为顶点集合的大小。

考虑到后面可能会使用到权值,因此需要一个大小和边的大小相同的二维数组来保存权值。

方法实现

添加顶点---addVex(T vex)

考虑到List可以动态扩容,而数组不可以。因此要考虑到将数组扩容的办法。所以需要两个列表,一个用来暂时承载保存边的二维数组的数据,一个暂时承载保存权值的二维数组的数据。当添加顶点的时候,先将二维数组中的数据放到对应的点中,通过重新实例化一个二维数组来实现扩容,然后再将数据返还给数组。

遍历顶点数组,看是否有重复的顶点存在与顶点列表中。若有,返回异常语句(下图);若没有,则将顶点加入至顶点集合中。

8fb149a4f62906c091bf08d8029590b3.png

删除顶点---removeVex(T vex)

删除也涉及顶点列表长度的变化,因此对于边的二维数组和权值二维数组,也需要使用相同的方法进行扩容。

遍历数组,看是否存在该点,若不存在,返回异常语句(下图);若存在,将其从点的集合中移除。

860eedd6dbdfaedbee7ac5dc216e77bb.png

添加边---addEdge(Edge edge)

因为边类中规定添加的参数有三个,其中两个是被该边连接的端点1和端点2。要遍历顶点数组,查看这两个顶点是否都存在。若不存在,返回异常语句(下图);则将这两个顶点在二维数组中的对应下标位置中的数据从0变为1。

db8af586d2e04eef28e0e619ff2b94dc.png

7948af669ee1a29336051040525283c5.png

关于存放权值的二维数组,在对应的位置也要更新为对应的权值数据。在横坐标与纵坐标相等时,即自己等于自己的时候,权值要为0。对于没有连接的两个点,要设定的一个较大的数值来表示两点不相连。(我这里用到的是10000)

删除边---removeEdge(Edge edge)

首先要查看目标边的两个顶点是否存在于顶点中,不存在就要返回异常语句。若存在,再看目标边是否存在,若不存在,返回异常语句(下图)。若存在,将目标边两个端点位于边数组的对应位置的数据要变为0。权值表中对应的位置要变为最大值。

e620fd0f564c64d746b63e2a6ebcffd0.png

边/点的数量---Vex/EdgeSize()

对于定点的的大小,直接返回顶点集合的大小即可。

对于边数量,需要遍历数组,看哪些位置是1的,然后记录1的个数,并将这些个数返回

d5be58a540c3520a5a58bf25b646f9dd.png

判断是否为空---isEmpty()

这里主要需要判断的是一个顶点集合是否为空,因为顶点集合为空,其他边也不存在。

b9fbc52f20782d3e6a1d45a773ce3034.png

广度优先迭代器---BoradTraverse(T StartVex)

初步实现:

队列实例化

迭代器实例化

访问数组实例化

主要实现:

将开始遍历点放进队列,并标记为已访问,由于实例化的访问数组长度和顶点集合的大小一致,所以找到对应点的下标,再在访问数组中变为true即可。然后将点的连接点输进队列中,并将该点从队列中弹出至迭代器中,然后循环做这步骤。最后迭代器中放的就是广度优先遍历的结果。

5f9da8dccf8729a548c69c2886bac739.png

fc023231bb4d2848b890b7fd3750a364.png

深度优先迭代器---depthTraverse(T StartVex)

初步实现:

因为深度优先遍历需要用到递归的方法,所以递归出来的点的顺序需要放在一个方法外的位置中,最后再把列表给打印出来。因此需要实例化一个存放顶点迭代顺序的迭代器。

访问数组实例化

主要实现:

输入目标点

传入迭代器中

标记为已访问

找邻接点

递归方法

2efbdf0c09da7f650af6b2deed50cc82.png

178f2591b8dcd8d09482f5f2cf001427.png

代码连接:

实验2:

十字链表也是存储图的一种形式,其结构比较复杂。对于每一个顶点都会有一个入弧和出弧,入弧是指指向这个点的边,出弧指的是从这个点出的边。

8b7f8c81fb252b6918de101b63465dcf.png

拿这幅图做例子,顶点F的入弧是A-F出弧;出弧是F-G。

对于每条边,它有四个要素,

弧尾:这条边出发的起始点

弧头:这条边指向的终点

同弧头:弧头相同的其他边。若无,则为空

同弧尾:弧尾相同的其他边。若无,则为空

df7378e6aec5c999c63600c87b18beed.png

实现十字链表存储图:

初步实现:

创建一个边的类,其中设置的变量有:边的权值,弧尾,弧头,同弧尾的边以及同弧头的边。并且要设定好构造方法,实例化边的时候要输入:权值、弧尾、弧头。

创建一个顶点的类,其中设置的变量有:入弧,出弧,数据。设定好构造方法,实例化顶点的时候要输入数据。

用顶点类创建一个顶点的集合来存放顶点

用边类来创建一个边的集合来存放边

方法实现:

添加顶点---addVex(Vex vex)

不像之前的邻接矩阵,这次的边是直接用一个列表来保存的,所以不需要对边的集合进行重组。同时,点的添加也没那么麻烦,只要直接添加进点的集合中就可以了。

删除顶点---removeVex(Vex vex)

除了直接在点的集合中进行删除,还要将涉及该点的边全部进行删除。

042d82361d8a2a3f2b772cedb569ce7f.png

9d636664cc1a03075c46406e3d0adf5a.png

添加边---addEdge(Edgeedge)

首先是直接将边添加进边的集合中。

然后获得该边的弧头和弧尾

看弧头弧或弧尾是否已有入弧或出弧。

若弧尾没有出弧,这条边会成为这个弧尾的出弧。如果该弧尾存在出弧,则寻找该弧尾出弧的同弧尾,直到最后一个同弧尾,这条边成为该弧尾出弧的新的最后的同弧尾。

若弧头没有入弧,这条边会成为这个弧头的入弧。如果该弧头存在入弧,则寻找该弧头出弧的同弧头,直到最后一个同弧头,这条边成为该弧头入弧的新的最后的同弧头。

删除边---removeEdge(Edgeedge)

因为保存边的是一个列表,所以比较容易删去目标边。用列表的remove功能可以实现。

36eaa0d3dfa7fa450d7c3ed47bc375e9.png

顶点/边的数量---vex/edgeSize()

因为保存边和顶点的都是一个列表,所以比较容易得到顶点和边的数量。用列表的size方法可以实现

是否为空---isEmpty()

因为保存顶点的是一个列表,所以比较容易得到图是否为空,用列表的isEmpty()方法可以实现。

广度优先遍历

实例化队列

实例化迭代器

实例化访问数组

输入起始遍历顶点

将起始遍历顶点放入队列中,并将其标记为已访问。

通过出弧入弧以及出弧的同弧头以及入弧的同弧尾来获取起始点的邻接点,将其入队,并用相同的方法去访问邻接点的邻接点,然后入队。将已访问的点标记直到访问的点的数量等于顶点集合的长度

将队列中的元素放进迭代器中并打印出来

2df515c5de43bab25724efd9aa909cc9.png

深度优先遍历

实例化列表来保存深度遍历的顶点顺序

实例化访问数组

对起始遍历点看它有没有出弧,有的话对出弧所对应的邻接点进行方法递归。检查完出弧后看有没有同弧尾,有的话对同弧尾对应的邻接点进行方法递归。同时要对访问过的点标记为已访问。遍历过程中对这些访问的点要放进保存顶点顺序的列表中。

将列表打印

af18e9b9c981bfbe4d3a6c2e4148f634.png

代码链接

实验3:

要解决最短路径可以使用一个方法:Dijkstra算法

把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 ,就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

实现方法

最短路径

传入一个带权值的二元数组,以及起始点

创建一个访问数组,并将起始点在访问数组的对应位置标记为已访问

以起始点在二元数组中的下标作为行

然后遍历该行,寻找最小的权值,并记录对应列下标i

当遇到不是邻接点的时候,遍历邻接点,看哪个邻接点离目标点近

将最小路径的值放入数组中

将对应顶点标记为已访问直到所有点都是已访问

打印数组

不相通点

查看开始点与哪个点的权值为10000,这两点不相通。

2406098a71df66571fd2f09797904859.png

caefbb237c36577f83d6da5b236bf144.png

实验知识点

邻接矩阵存储图

十字链存储图

最短路径的算法——Dijkstra算法

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

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

相关文章

C语言指针变量的运算

前言指针变量也是可以进行运算的,如指针变量对其自身加上某个整数或减去某个整数,这在内存上体现为:相对这个指针向后偏移多少个单位或向前偏移了多少个单位,这里的单位与指针变量的类型有关。在32bit环境下,int类型占…

关于n对角矩阵数据结构_机器学习与线性代数 - 特殊矩阵

在线性代数中,有一些特殊的矩阵具有易于分析和操作的特性。它们的特征向量可能具有特定的特征值或特殊关系。还有一些方法可以将一个矩阵分解成这些“更简单”的矩阵。操作复杂性的降低提高了可伸缩性。然而,即使这些矩阵都是特殊的,它们也不…

java初学者指南_企业Java中事务隔离级别的初学者指南

java初学者指南介绍 基于ACID事务属性的关系数据库强一致性模型。 在本文中,我们将阐明对资源本地事务和JTA事务使用不同的事务隔离级别和各种配置模式的背后原因。 隔离和一致性 在关系数据库系统中,原子性和持久性是严格的属性,而一致性和…

C语言内存/指针相关

内存数据类型–更好的内存管理数据类型:固定大小内存的别名typedef结构体的别名 typedef struct Student MyStudent给指针起别名 typedef char * PCHAR给变量起别名 typedef longlong mylong_t注意:void类型不能typedefvoid只能对函数返回和参数的限定vo…

c程序怎么改为java程序_如何将Java程序的入口点更改为C签名?

我在JNA试图在Java程序中执行一些C代码时愚弄.这是我在网上找到的一个工作示例(构建路径中需要JNA):package core;import com.sun.jna.Library;import com.sun.jna.Native;import com.sun.jna.Platform;public class CoreController {public interface CLibrary ext…

求杨辉三角的前n行数据_LeetCode算法第118题:杨辉三角

题目描述:给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。在杨辉三角中,每个数是它左上方和右上方的数的和。示例:输入: 5输出:[ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1]]思路:杨辉三角形有如下两个特性每一行的第…

jasmine单元测试_使用Jasmine,Spock和Nashorn测试JVM服务器端JavaScript

jasmine单元测试JavaScript使用不仅限于浏览器中的客户端代码或NodeJS支持的服务器端代码。 许多基于JVM的项目都将其用作内部脚本语言。 测试这种功能既不简单也不标准。 在本文中,我打算演示一种使用成熟的工具(例如Jasmine , Spock和Nasho…

常用于单片机的接口适配器模式C语言实现

一般实现在我们做项目的时候,一般的实现,可能我们会这样写代码// FileName: test.c// 来源:公众号【技术让梦想更伟大】#include#include “ExternModule.h” int main(void){/*初始化*/ vAllInit(); while(1) { /*项目逻辑*/ vLo…

java判断线程是否死锁_c++多线程锁 Mutex  自动判断死锁

c多线程锁可以使用absl::Mutex std::mutex这两种,下面是demo代码。使用absl:Mutex的时候打印:[mutex.cc : 1338] RAW: Cycle:[mutex.cc : 1352] RAW: mutex0x683b68 stack: 0x438562 absl::DebugOnlyDeadlockCheck() 0x4387b2 absl::Mutex::Lock() 0x43…

ar面部识别_国内手机厂商AR布局报告

欢迎关注AIRX的B站官方账号:AIRX社区,我们会定期和一些ARVR、AI企业和高校合作直播,分享前沿ARVR、AI、Unity、Unreal技术和教程。招运营、UI设计志愿者进行时,我们期待您的加入~文章来源 :增强现实核心技术…

rest服务swagger_在Java EE 7上骑骆驼–带有Swagger文档的REST服务

rest服务swagger骆驼开箱即用。 Swagger集成就是其中之一。 不幸的是,大多数已经存在的功能都严重依赖于Spring。 但这并不能阻止我们在普通的Java EE 7应用程序中使用它们,因为有时它只是更轻量级的处理方式。 但是我不想再对此进行讨论。 相反&#xf…

知识贴!单片机C语言编程之.H文件与.C文件的关系

一、.H文件与.C文件的关系:迄今为止,写过的程序都是一些很简单的程序,从来没有想到要自己写.H文件,也不知道.H文件到底什么用,与.C文件什么关系。只是最近写键盘程序,参考别人的程序时,发现别人…

java stream 分组求和_Java stream List 求和、分组操作

Java stream List 求和、分组操作前言项目中经常会使用Stream操作一些集合数据,今天记录一下我经常使用的Stream操作求和操作public static void main(String[] args) {List users generateUserList();int reduce users.stream().mapToInt(x -> x.getSalary().…

vector怎么按字段查询顺序输出_7大查询匹配类函数,一次给你总结好

Excel数据处理中,经常用到各种函数,可以说函数是Excel必不可少的一部分,今天向大家介绍数据处理中的七个查询匹配函数。下面一一介绍各函数的具体用法。vlookup功能:搜索表区域首列满足条件的元素,确定待检索单元格在区…

hibernate连接泄露_泄漏抽象,或如何正确地与Hibernate绑定Oracle DATE

hibernate连接泄露我们最近发布了一篇文章,介绍如何在SQL / JDBC和jOOQ中正确绑定Oracle DATE类型 。 这篇文章在Reddit上颇受关注, Vlad Mihalcea对此发表了有趣的评论,他经常在他的博客上撰写有关Hibernate,JPA,事务…

信工干货||C语言中的运算符和表达式

C语言中的运算符和表达式1算术运算符及表达式(1)算术运算符包括: ,-,*,/,%。(2)*,/,%同级,比 ,-高。(3&#x…

java程会释放锁join_关于join() 是否会释放锁的一些思考

# 首先从一个很有意思的问题开始:- 问 : Thread 的join() 方法是否会释放锁?- 答: 会!# 如果一切到这里就结束了,那可能也就没有这篇小记了,但是我的脑子却冒出了一些奇怪的想法:- 释…

java lambda::_书评:精通Lambda:多核世界中的Java编程

java lambda::从版本8开始,λ编程(lambda编程)终于在Java世界中引入。此功能将在很大程度上改变Java开发人员的编程方式以及针对样板代码的新“武器”。 Java 8通过引入新的Stream API,大部分已将函数式编程应用在Collections API…

3皮卡丘眨眼代码_活见久,皮卡丘居然是一门编程语言

我很荣幸地向你介绍皮卡神教的编程语言,这门语言专为皮神设计(认真脸)。为什么一定要学习这门语言呢——谁不想要只皮卡丘我问你?在当今的宝可梦就业环境中,大多数皮卡丘们都在残忍的宝可梦训练师手下过着顺从和被奴役的生活。他们经常被迫与…

C语言关系运算符详解

关系运算符在使用时,它的的两边都会有一个表达式,比如变量、数值、加减乘除运算等,关系运算符的作用就是判明这两个表达式的大小关系。注意,是判明大小关系,不是其他关系。C语言提供了以下关系运算符:关系运…