数据结构与算法

图的邻接表和邻接矩阵表示法以及kruskal&prim算法求最小生成树

图的邻接表表示

概念如下:邻接表
       其实我们大可以使用hashmap构建邻接表,但是为了深入理解邻接表的数据结构,以及其数组—链表表示,现给出代码:

package FifteenWeek;/*** 邻接表* @author Hello**/
public class AdjacencyList {// 邻接表中表对应的链表的顶点private class ENode{int ivex;           // 该边所指向的顶点的位置ENode next;           // 指向下一条弧的指针}// 邻接表中表的顶点private class VNode {char data;          // 顶点信息ENode firstEdge;    // 指向第一条依附该顶点的弧};private VNode[] mVexs;  // 顶点数组/*** * @param vexs     :  [A,B,C,D,E,F,G]* @param edges : {[A,B],[B,C],[B,E],[B,F],[C,E],[D,C],[E,B],[E,D],[F,G]}*/public AdjacencyList(char[] vexs, char[][] edges){// 初始化"顶点数"和"边数"int vlen = vexs.length;int elen = edges.length;// 初始化"顶点"mVexs = new VNode[vlen];for (int i = 0; i < mVexs.length; i++) {mVexs[i] = new VNode();mVexs[i].data = vexs[i];mVexs[i].firstEdge = null;}// 初始化"边"for (int i = 0; i < elen; i++) {// 读取边的起始顶点和结束顶点char c1 = edges[i][0];char c2 = edges[i][1];// 读取边的起始顶点和结束顶点int p1 = getPosition(edges[i][0]);int p2 = getPosition(edges[i][1]);// 初始化node1ENode node1 = new ENode();node1.ivex = p2;// 将node1链接到"p1所在链表的末尾"if(mVexs[p1].firstEdge == null)mVexs[p1].firstEdge = node1;elselinkLast(mVexs[p1].firstEdge, node1);}}/** 返回ch在mVexs中的位置*/private int getPosition(char ch) {for(int i=0; i<mVexs.length; i++)if(mVexs[i].data==ch)return i;return -1;}/** 将(Enode) node节点链接到(Enode) list的最后*/private void linkLast(ENode list, ENode node) {ENode p = list;while(p.next!=null)p = p.next;p.next = node;}
}

图的邻接矩阵表示

这个比较简单,即所谓的map[i][j]=k表示从图的顶点i到顶点j得到的边的权重(权值)为k,对于无向图而言,它的邻接矩阵是个对称阵。

kruskl算法

概念如下:kruskal算法
       其实通过这种“单步”贪心算法得到的结果并不总是最小生成树,但因其简洁性以及综合权值也足够小,故而有所推广,值得学习:

package FifteenWeek;/*** line 76 必须要+1* @author Hello**/
public class Kruskal {private static final int MAX=Integer.MAX_VALUE;public static void main(String[] args) {// TODO Auto-generated method stub//邻接矩阵表示的无向图int[][] map = new int[][]{{0,10,MAX,MAX,MAX,11,MAX,MAX,MAX},{10,0,18,MAX,MAX,MAX,16,MAX,12},{MAX,MAX,0,22,MAX,MAX,MAX,MAX,8},{MAX,MAX,22,0,20,MAX,MAX,16,21},{MAX,MAX,MAX,20,0,26,MAX,7,MAX},{11,MAX,MAX,MAX,26,0,17,MAX,MAX},{MAX,16,MAX,MAX,MAX,17,0,19,MAX},{MAX,MAX,MAX,16,7,MAX,19,0,MAX},{MAX,12,8,21,MAX,MAX,MAX,MAX,0}};kruskal(map);}private static void kruskal(int[][] map) {// TODO Auto-generated method stubint num=map.length, sum=0;int[] edge=new int[3];//端点1, 端点2, 权重DisjointSet closure=new DisjointSet(num+1);//并查集类参考上期while(pos(closure.node) < map.length-1){//之所以要-1是因为第一次加入两个端点时closure.node数组里面只有一个正值,另一个依旧是-1(用于表示根节点)edge=findMin(map);while((closure.search(edge[0]) == closure.search(edge[1])) && (edge[0]!=0 && edge[1]!=0))edge=findMin(map);closure.union(edge[0], edge[1]);//System.out.println(pos(closure.node));sum+=edge[2];print(closure.node);}System.out.println("sum : "+sum);}private static void print(int[] node) {// TODO Auto-generated method stubSystem.out.println("node : ");for(int i=0;i<node.length;i++)System.out.print(node[i]+", ");System.out.println();}private static int pos(int[] node) {//返回node[]中有几个正数(已经压入了几个端点)// TODO Auto-generated method stubint count=0;for(int i=0;i<node.length;i++)if(node[i] >= 0) count++;return count;}private static int[] findMin(int[][] map) {// TODO Auto-generated method stubint min=MAX, n1=0, n2=0;for(int i=0; i<map.length; i++)for(int j=0; j<i; j++)if(map[i][j] < min){min=map[i][j];n1=i;n2=j;}map[n1][n2]=MAX;return new int[]{n1+1, n2+1, min};//必须要+1!!!!}}

结果如下:

node :
-1, -1, -1, -1, -1, -2, -1, -1, 5, -1,
node :
-1, -1, -1, -2, -1, -2, -1, -1, 5, 3,
node :
-1, -2, 1, -2, -1, -2, -1, -1, 5, 3,
node :
-1, -3, 1, -2, -1, -2, 1, -1, 5, 3,
node :
-1, -5, 1, 1, -1, -2, 1, -1, 5, 3,
node :
-1, -6, 1, 1, -1, -2, 1, 1, 5, 3,
node :
-1, -6, 1, 1, 5, -3, 1, 1, 5, 3,
node :
-1, -9, 1, 1, 5, 1, 1, 1, 5, 3,
sum : 99

prim算法

概念如下:prim算法
       与kruskal有所不同的是, prim选择从某一既定顶点出发,每次“合并”一个顶点之后可供选择的边数也要加上新顶点可直接选择的边,然后再从这些边中不断选择最小权值的边即可。

代码如下:

package FifteenWeek;import java.util.Arrays;public class Prim {private static final int max=Integer.MAX_VALUE;private static int[][] map = new int[][]{{0,10,max,max,max,11,max,max,max},{10,0,18,max,max,max,16,max,12},{max,max,0,22,max,max,max,max,8},{max,max,22,0,20,max,max,16,21},{max,max,max,20,0,26,max,7,max},{11,max,max,max,26,0,17,max,max},{max,16,max,max,max,17,0,19,max},{max,max,max,16,7,max,19,0,max},{max,12,8,21,max,max,max,max,0}};public static void main(String args[]){prim();}private static void prim() {// TODO Auto-generated method stubint len=map.length, sum=0;int[] lowcost;int[] nearvex = new int[len];int[][] map2 = new int[len][len];DisjointSet closure=new DisjointSet();lowcost=map[0]; Arrays.fill(nearvex, 0);lowcost[0]=max; nearvex[0]=-1;for(int i=0;i<len-1;i++){//因为到了第8次循环的时候就nearvex[]已经有了9个-1了,刚好形成连通图int[] edge=findMin(lowcost);//System.out.println(nearvex[edge[0]]+", "+edge[0]);//edge[0] : 一条边的终点; edge[1] : value//nearvex[edge[0]] : 一条边的起点map2[nearvex[edge[0]]][edge[0]]=edge[1];map2[edge[0]][nearvex[edge[0]]]=edge[1];nearvex[edge[0]]=-1;//设置-1表示该下标edge[0](即新边的终点)已经加入连通图,无需继续在这个顶点上费时lowcost=getMin(map[edge[0]], lowcost, nearvex, edge[0]);}print(map2);}private static void print(int[][] map2) {// TODO Auto-generated method stubfor(int i=0;i<map2.length;i++){for(int j=0;j<map2[0].length;j++)System.out.print(map2[i][j]+", ");System.out.println();}}private static int[] getMin(int[] is, int[] lowcost, int[] nearvex, int start) {// TODO Auto-generated method stubint[] low=new int[lowcost.length];for(int i=0;i<low.length;i++){if(nearvex[i]==-1) low[i]=max;else{low[i]=Math.min(is[i], lowcost[i]);nearvex[i]=(is[i] < lowcost[i]) ? start : nearvex[i];//当新顶点的加入使得它到顶点i的距离更短时,需要修改nearvex[],使i下标处表示的起点为这个新顶点!!!}}return low;}private static int[] findMin(int[] lowcost) {// TODO Auto-generated method stubint index=0, min=max;for(int i=0;i<lowcost.length;i++)if(lowcost[i]<min){index=i;min=lowcost[i];}lowcost[index]=max;return new int[]{index, min};}}

结果如下:

0, 10, 0, 0, 0, 11, 0, 0, 0,
10, 0, 0, 0, 0, 0, 16, 0, 12,
0, 0, 0, 0, 0, 0, 0, 0, 8,
0, 0, 0, 0, 0, 0, 0, 16, 0,
0, 0, 0, 0, 0, 0, 0, 7, 0,
11, 0, 0, 0, 0, 0, 0, 0, 0,
0, 16, 0, 0, 0, 0, 0, 19, 0,
0, 0, 0, 16, 7, 0, 19, 0, 0,
0, 12, 8, 0, 0, 0, 0, 0, 0,

【典型习题整理】数据结构与算法作业相关推荐

  1. 记一次数据结构与算法作业:利用循环和递归输出1-N的正整数的程序分析比较

    随便记录一次数据结构与算法的分析作业,内容为分析循环和递归实现输出1-N的正整数的对比.从时间和空间上分析了两种方式实现的递归方法和循环区别. 一.数据记录图表 二.分析 第一张图表制作时由于在打游戏 ...

  2. 数据结构与算法作业3——约瑟夫环问题(循环链表)

     第二次作业: 习题2 载具杀手与时停高手(约瑟夫环问题) 著名绅士简尚夫有一项特殊的天赋,他可以摧毁任意一辆载具(载具杀手).他的朋友狄傲可以将时间暂停(时停高手).他俩玩一个游戏. 有N辆车,编号 ...

  3. python思想读后感_数据结构与算法:Python语言描述读后感1000字

    <数据结构与算法:Python语言描述>是一本由裘宗燕著作,机械工业出版社出版的平装图书,本书定价:CNY 45.00,页数:343,特精心从网络上整理的一些读者的读后感,希望对大家能有帮 ...

  4. Python数据结构与算法(一)--算法和时间复杂度

    最近下班一直在学习和总结Python,最近在整理数据结构和算法这方面的知识,虽然大学的时候也学过数据结构(c语言版本),但是工作这几年一直在做前端所以,这方面的知识也忘了差不多,所以就想整理一下,方便 ...

  5. c语言将AOE网络的数据写入TXT文档中,数据结构与算法学习辅导及习题详解.张乃孝版-C/C++文档类资源...

    数据结构与算法学习辅导及习题详解.张乃孝版.04年10月 经过几年的努力,我深深体会到,编写这种辅导书要比编写一本湝通教材困难得多. 但愿我的上述理想,在本书中能够得以体现. 本书的组织 本书继承了& ...

  6. 常见数据结构与算法整理总结(下)

    原文链接:https://www.jianshu.com/p/42f81846c0fb 这篇文章是常见数据结构与算法整理总结的下篇,上一篇主要是对常见的数据结构进行集中总结,这篇主要是总结一些常见的算 ...

  7. python基础教程第三版豆瓣-数据结构与算法必读书单吐血整理推荐【附网盘链接】...

    前言:技术书阅读方法论 一.速读一遍(最好在1~2天内完成) 人的大脑记忆力有限,在一天内快速看完一本书会在大脑里留下深刻印象,对于之后复习以及总结都会有特别好的作用. 对于每一章的知识,先阅读标题, ...

  8. 《数据结构与算法 C语言版》—— 3.8习题

    本节书摘来自华章出版社<数据结构与算法 C语言版>一 书中的第3章,第3.8节,作者:徐凤生,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 3.8习题 1名 ...

  9. 《数据结构与算法 C语言版》—— 2.7习题

    本节书摘来自华章出版社<数据结构与算法 C语言版>一 书中的第2章,第2.7节,作者:徐凤生,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 2.7习题 1描 ...

最新文章

  1. asp.net c#截取指定字符串函数
  2. InfluxDB 开源分布式时序、事件和指标数据库
  3. 网格弹簧质点系统模拟(Spring-Mass System by Verlet Integration)附源码
  4. boost::filesystem模块实现Windows MAX_PATH的测试程序
  5. [css] 如果css文件过大时,如何异步加载它?
  6. 【LightOJ - 1038】Race to 1 Again(概率dp,数学期望)
  7. Mybatis_day1
  8. 利用RC.EXE和RCDLL.DLL创建VB6资源文件
  9. mongodb update ()命令
  10. Linux命令行上传本地文件到服务器 、 下载服务器文件到本地
  11. 同质化代币和非同质化代币 区别对比
  12. Codeforces_Round527_Div3_C题--Prefixes and Suffixes
  13. 关于Activity跳转动画大汇总
  14. MATLAB中LINGO软件及数学规划问题应用
  15. 阿里云服务器“禁止外国IP访问服务器”和“禁止服务器访问外国IP”的安全组策略配置方法
  16. 微信对话生成器V4.4绿色版,自定义生成微信聊天截图软件(资源供学习参考)
  17. windows下创建多个回收站
  18. 【原创】2019.08.15 模拟赛 ※ [USACO19]Left Out / [USACO19]Cow Steeplechase II / bzoj 4972 小Q的方格纸
  19. Unity3d场景渲染出图
  20. 演讲 口才 思维导图

热门文章

  1. es数据库集群以及中文分词
  2. 软考前半个月该如何学习
  3. 三位数自动递增编号函数_excel中如何使用SUBTOTAL函数实现自动连续四位数编号...
  4. 2019/6/14 乐檬-Java后端开发实习
  5. easyUI实现日历
  6. 2022-2028全球及中国自动运输网络(ATN)系统市场研究
  7. JAVA大学生心愿墙系统计算机毕业设计Mybatis+系统+数据库+调试部署
  8. 【win10】磁盘保护清除
  9. 从零开始的ORB_SLAM3运行
  10. 【保姆级教程】Docker基础操作篇-Dokerfile(含源码)