图之深度优先生成森林
来源:互联网 发布:小光头脸型数据 编辑:程序博客网 时间:2024/04/28 20:52
生成森林是指由非连通图的连通分量的生成树所组成的森林,而深度优先生成森林则指由图的深度优先遍历算法获得的生成森林。
下面给出非连通图的深度优先生成森林算法的Java实现,其中生成森林采用孩子兄弟链表存储结构。
1. 深度优先生成森林算法实现
package org.sky.graph;import java.util.Scanner;public class DeepFirstSearchForest { //表结点,包含边的相关信息 @SuppressWarnings("unused") private static class ArcNode{ int adjVex; //该弧或边所指向的顶点的位置 int value; //与弧或边相关的信息,如权值 ArcNode nextArc; //指向下一条弧或边的指针 public ArcNode(int adjVex, int value) { super(); this.adjVex = adjVex; this.value = value; } ArcNode(int adjvex, int value, ArcNode nextArc) { super(); this.adjVex = adjvex; this.value = value; this.nextArc = nextArc; } public int getAdjVex() { return adjVex; } public void setAdjVex(int adjVex) { this.adjVex = adjVex; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public ArcNode getNextArc() { return nextArc; } public void setNextArc(ArcNode nextArc) { this.nextArc = nextArc; } } //头结点,对应图中的顶点 @SuppressWarnings("unused") private static class VNode{ Object data; //顶点信息 ArcNode firstArc; //指向第一条依附该顶点的弧或边的指针 public VNode(Object data) { super(); this.data = data; } public VNode(Object data, ArcNode firstArc) { super(); this.data = data; this.firstArc = firstArc; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public ArcNode getFirstArc() { return firstArc; } public void setFirstArc(ArcNode firstArc) { this.firstArc = firstArc; } } private int numVex; //图的当前顶点数 private int numArc; //图的当前边数或弧数 private VNode[] vexs; //存储表头结点,通常采用顺序存储结构 public DeepFirstSearchForest() { super(); } public DeepFirstSearchForest(int numVex, int numArc, VNode[] vexs) { super(); this.numVex = numVex; this.numArc = numArc; this.vexs = vexs; } /** * @Desciption 创建有向网 */ public void createDN(){ Scanner sc = new Scanner(System.in); System.out.println("请分别输入图的顶点数及边数"); numVex = sc.nextInt(); numArc = sc.nextInt(); vexs = new VNode[numVex]; System.out.println("请分别输入图的各个顶点:"); for(int v = 0; v < numVex; v++){ vexs[v] = new VNode(sc.next()); } System.out.println("请输入各个边的来给你个顶点及其权值"); for(int k = 0; k < numArc; k++){ int v = locateVex(sc.next()); int u = locateVex(sc.next()); int value = sc.nextInt(); addArc(v,u,value); } sc.close(); } /** * @Desciption 创建无向网 */ public void createUDN(){ Scanner sc = new Scanner(System.in); System.out.println("请分别输入图的顶点数及边数"); numVex = sc.nextInt(); numArc = sc.nextInt(); vexs = new VNode[numVex]; visited = new boolean[numVex]; System.out.println("请分别输入图的各个顶点:"); for(int v = 0; v < numVex; v++){ vexs[v] = new VNode(sc.next()); visited[v] = false; } System.out.println("请输入各个边的来给你个顶点及其权值"); for(int k = 0; k < numArc; k++){ int v = locateVex(sc.next()); int u = locateVex(sc.next()); int value = sc.nextInt(); addArc(v,u,value); addArc(u,v,value); } sc.close(); } /** * @Desciption 返回与传入值相对应的定点位置 */ public int locateVex(Object vex){ for(int v = 0; v < numVex; v++){ if(vexs[v].getData().equals(vex)){ return v; } } return -1; } /** * @Desciption 在位置v和u间添加边,并赋权值 */ private void addArc(int v, int u, int value){ ArcNode arc = new ArcNode(u,value); arc.setNextArc(vexs[v].getFirstArc()); vexs[v].setFirstArc(arc); }///////////////////////////////////////深度优先生成森林(以孩子兄弟链表作生成森林的存储结构)////////////////////////////////////////////// //孩子兄弟链表内部类 public class CSNode{ Object data; CSNode firstChild; CSNode nextSibling; public CSNode(Object data, CSNode firstChild, CSNode nextSibling) { super(); this.data = data; this.firstChild = firstChild; this.nextSibling = nextSibling; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public CSNode getFirstChild() { return firstChild; } public void setFirstChild(CSNode firstChild) { this.firstChild = firstChild; } public CSNode getNextSibling() { return nextSibling; } public void setNextSibling(CSNode nextSibling) { this.nextSibling = nextSibling; } } private boolean[] visited; //访问标志数组 private CSNode T = null; //孩子兄弟链表 /** * 深度优先遍历建立无向图的深度优先生成森林 */ public void DFSTraverse(){ CSNode q = null; //指向当前生成树的根 for(int v = 0; v < numVex; v++){ if(!visited[v]){ CSNode p = new CSNode(vexs[v].getData(), null, null); if(T == null){ T = p; //第一棵生成树的根 }else{ q.setNextSibling(p); //其他生成树的根 } q = p; //指向当前生成树的根 DFSTree(vexs, v, p); //对尚未访问的顶点调用DFS } } } /** * 从第v个顶点出发递归地深度优先遍历图 * @param vexs * @param v */ public void DFSTree(VNode[] vexs, int v, CSNode T){ visited[v] = true; System.out.println(vexs[v].getData()); //输出访问的结点 boolean first = true; CSNode q = null; //指向当前生成树的根 for(int w = getFirstAdjVex(v); w >= 0; w = getNextAdjVex(v , w)){ if(!visited[w]){ CSNode p = new CSNode(vexs[w].getData(), null, null); if(first){ //w是v的第一个未被访问的邻接顶点 T.setFirstChild(p); //根的左孩子结点 first = false; }else{ //w是v的其他未被访问的邻接顶点 q.setNextSibling(p);//上一个邻接顶点的右兄弟结点 } q = p; DFSTree(vexs, w, q); //对尚未访问的顶点调用DFS } } } /** * 获取vexs[v]的第一个邻接弧的顶点位置 * @param vexs * @param v * @return vexs[v]的第一个邻接弧的顶点位置;若不存在,则返回-1 */ public int getFirstAdjVex(int v){ if(vexs[v].firstArc != null){ //第一个邻接弧是否存在 return vexs[v].firstArc.adjVex; } return -1; } /** * 获取vexs[v]的相对第一个邻接弧的下一个邻接弧的顶点位置 * @param v * @param w * @return vexs[v]的相对第一个邻接弧的下一个邻接弧的顶点位置;若不存在,则返回-1 */ public int getNextAdjVex(int v, int w){ ArcNode temp = vexs[v].firstArc; int tempTail = -1; while(temp != null){ if(temp.adjVex == w){ temp = temp.nextArc; if(temp != null){ tempTail = temp.adjVex; break; } }else{ temp = temp.nextArc; } } return tempTail; }}
2. 测试代码
package org.sky.graph;public class TestGragh { public static void main(String[] args){ DeepFirstSearchForest dfsForest = new DeepFirstSearchForest(); dfsForest.createUDN(); dfsForest.DFSTraverse(); }}
0 0
- 图之深度优先生成森林
- 无向图中的深度优先生成森林
- 深度优先遍历之迷宫生成算法
- 无向图中的广度优先生成森林
- 图算法之深度优先
- 图之深度优先搜索
- 深度优先生成树
- 生成图-深度优先搜索/宽度优先搜索
- 图之图的深度优先遍历
- 图之图的深度优先遍历
- 图之图的深度优先遍历
- 图之图的深度优先遍历
- python数据结构之图深度优先和广度优先
- python数据结构之图深度优先和广度优先
- 图的遍历 之 深度优先搜索
- 图遍历之深度优先搜索
- 数据结构之图的深度优先搜索
- 图深度优先搜索之二染色
- LeetCode204—Count Primes
- 流言算法--gossip算法
- Spring4.3.5+struts2-2.5.8+hibernate4.3.11整合配置
- markdwon 的表格内容含有字符“|”时
- C# AspriseOCR 验证码识别(第二讲)
- 图之深度优先生成森林
- 元组排序
- FFMPEG结构体之AVOutputFormat
- Hbase启动失败:zookeeper.MetaTableLocator: Failed verification of hbase:meta,,1 at address=worker
- 写在2017年的年初
- MySQL中表与表之间进行复制
- Mac自带apache+php环境配置
- DOM事件的处理
- MATLAB之数学运算