Java实现图的深度和广度优先遍历算法

概述:

近期要学习写网络爬虫。所以把图的深度和广度搜索都再温习一下。

图结构展示:

实现过程:

首先,我们来看看图结构在代码中的实现。有三块逻辑:

1.图中的节点:

public class GraphNode {

	public List<GraphEdge> edgeList = null;

	private String label = "";

	public GraphNode(String label) {
		this.label = label;
		if (edgeList == null) {
			edgeList = new ArrayList<GraphEdge>();
		}
	}

	/**
	 * 给当前节点加入一条边
	 * GraphNode
	 * @param edge
	 * 			加入的边
	 */
	public void addEdgeList(GraphEdge edge) {
		edgeList.add(edge);
	}

	public String getLabel() {
		return label;
	}
}

2.图中的边:

public class GraphEdge {

	private GraphNode nodeLeft;

	private GraphNode nodeRight;

	/**
	 * @param nodeLeft
	 * 			边的左端
	 * @param nodeRight
	 * 			边的右端
	 */
	public GraphEdge(GraphNode nodeLeft, GraphNode nodeRight) {
		this.nodeLeft = nodeLeft;
		this.nodeRight = nodeRight;
	}

	public GraphNode getNodeLeft() {
		return nodeLeft;
	}

	public GraphNode getNodeRight() {
		return nodeRight;
	}

}

3.把节点和边组合成一个图结构:

public class MyGraph {

	private List<GraphNode> nodes = null;

	public void initGraph(int n) {
		if (nodes == null) {
			nodes = new ArrayList<GraphNode>();
		}

		GraphNode node = null;
		for (int i = 0; i < n; i++) {
			node = new GraphNode(String.valueOf(i));
			nodes.add(node);
		}
	}

	public void initGraph(int n, boolean b) {
		initGraph(n);
		GraphEdge edge01 = new GraphEdge(nodes.get(0), nodes.get(1));
		GraphEdge edge02 = new GraphEdge(nodes.get(0), nodes.get(2));
		GraphEdge edge13 = new GraphEdge(nodes.get(1), nodes.get(3));
		GraphEdge edge14 = new GraphEdge(nodes.get(1), nodes.get(4));
		GraphEdge edge25 = new GraphEdge(nodes.get(2), nodes.get(5));
		GraphEdge edge26 = new GraphEdge(nodes.get(2), nodes.get(6));
		GraphEdge edge37 = new GraphEdge(nodes.get(3), nodes.get(7));
		GraphEdge edge47 = new GraphEdge(nodes.get(4), nodes.get(7));
		GraphEdge edge56 = new GraphEdge(nodes.get(5), nodes.get(6));

		nodes.get(0).addEdgeList(edge01);
		nodes.get(0).addEdgeList(edge02);
		nodes.get(1).addEdgeList(edge13);
		nodes.get(1).addEdgeList(edge14);
		nodes.get(2).addEdgeList(edge25);
		nodes.get(2).addEdgeList(edge26);
		nodes.get(3).addEdgeList(edge37);
		nodes.get(4).addEdgeList(edge47);
		nodes.get(5).addEdgeList(edge56);
	}

	public void initGraph() {
		initGraph(8, false);
	}

	public List<GraphNode> getGraphNodes() {
		return nodes;
	}
}

有了图的结构,我们就能够进行一些实际的操作了。

深度优先搜索:

public class DFSearch {

	/**
	 * 深度遍历
	 * DFSearch
	 * @param node
	 * 			当前节点
	 * @param visited
	 * 			被訪问过的节点列表
	 */
	public void searchTraversing(GraphNode node, List<GraphNode> visited) {
		// 推断是否遍历过
		if (visited.contains(node)) {
			return;
		}

		visited.add(node);
		System.out.println("节点:" + node.getLabel());
		for (int i = 0; i < node.edgeList.size(); i++) {
			searchTraversing(node.edgeList.get(i).getNodeRight(), visited);
		}
	}
}

广度优先搜索:

public class BFSearch {

	/**
	 * 广度优先搜索
	 * BFSearch
	 * @param node
	 * 			搜索的入口节点
	 */
	public void searchTraversing(GraphNode node) {
		List<GraphNode> visited = new ArrayList<GraphNode>(); // 已经被訪问过的元素
		Queue<GraphNode> q = new LinkedList<GraphNode>(); // 用队列存放依次要遍历的元素
		q.offer(node);

		while (!q.isEmpty()) {
			GraphNode currNode = q.poll();
			if (!visited.contains(currNode)) {
				visited.add(currNode);
				System.out.println("节点:" + currNode.getLabel());
				for (int i = 0; i < currNode.edgeList.size(); i++) {
					q.offer(currNode.edgeList.get(i).getNodeRight());
				}
			}
		}
	}
}

执行结果:

源代码下载:

http://download.csdn.net/detail/u013761665/8968443

时间: 2024-10-05 18:54:46

Java实现图的深度和广度优先遍历算法的相关文章

【数据结构-图】图的建立以及广度优先遍历算法

本文利用邻接表的方法将图进行了表示,并且利用广度优先遍历方法对图进行遍历 下面是一个图的示例: 代码如下: #include<iostream> using namespace std; typedef int VexType; typedef struct Arcnode{ VexType data; struct Arcnode *nextarc; }ArcNode; typedef struct Vexnode { VexType data; ArcNode *firstarc; }Vn

浅谈数据结构之图的邻接表深度和广度优先遍历(九)

邻接矩阵是一种不错的图存储结构,但是我们发现,对于边数相对较少的图,这种结构是存在对存储空间的极大浪费的.我们知道,顺序存储结构存在预先分配内存可能造成空间浪费的问题,于是引出了链式存储的结构.同样的,我们也可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题.因此,对于图的存储结构,我们同样引入了一种数组与链表相组合的存储方法,我们一般称之为邻接表. 邻接表的处理方法是这样的:(1).图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过数组可以较容易的读取顶点的信息,更加方便:另

数据结构课设——有向图的深度、广度优先遍历及拓扑排序

任务:给定一个有向图,实现图的深度优先, 广度优先遍历算法,拓扑有序序列,并输出相关结果. 功能要求:输入图的基本信息,并建立图存储结构(有相应提示),输出遍历序列,然后进行拓扑排序,并测试该图是否为有向无环图,并输出拓扑序列. 按照惯例,先上代码,注释超详细: #include<stdio.h> #include<stdlib.h> #include<malloc.h> #pragma warning(disable:4996) #define Max 20//定义数

《图论》——广度优先遍历算法(BFS)

十大算法之广度优先遍历: 本文以实例形式讲述了基于Java的图的广度优先遍历算法实现方法,详细方法例如以下: 用邻接矩阵存储图方法: 1.确定图的顶点个数和边的个数 2.输入顶点信息存储在一维数组vet中 3.初始化邻接矩阵. 4.依次输入每条边存储在邻接矩阵array中 输入边依附的两个顶点的序号i,j. 将邻接矩阵的第i行第j列的元素值置为1: 将邻接矩阵的第j行第i列的元素值置为1: 广度优先遍历实现: 1.初始化队列Q 2.訪问顶点v:ifVisit[v]=1;顶点v入队Q; 3.whi

广度优先遍历算法(BFS)

十大算法之广度优先遍历: 本文以实例形式讲述了基于Java的图的广度优先遍历算法实现方法,具体方法如下: 用邻接矩阵存储图方法: 1.确定图的顶点个数和边的个数 2.输入顶点信息存储在一维数组vet中 3.初始化邻接矩阵: 4.依次输入每条边存储在邻接矩阵array中 输入边依附的两个顶点的序号i,j: 将邻接矩阵的第i行第j列的元素值置为1: 将邻接矩阵的第j行第i列的元素值置为1: 广度优先遍历实现: 1.初始化队列Q 2.访问顶点v:ifVisit[v]=1;顶点v入队Q; 3.while

图的深度和广度遍历(邻接矩阵)

这里我采用邻接矩阵的存储方式对图进行遍历 #include <iostream> #include <queue> #define INFINITY 100 #define MAXNODE 100 #define OK 1 using namespace std; typedef char VertexType; int vis[MAXNODE]; typedef struct { int adj; } ArcType; typedef struct { VertexType ve

图的邻接表存储表示,图的深度优先和广度优先遍历

1 #include<stdio.h> 2 #include<stdlib.h> 3 4 #define MAX_VERTAX_SIZE 20 5 #define OK 1 6 #define ERROR 0 7 8 typedef int Status; 9 typedef char ElemType; 10 11 typedef struct EageNode{ 12 int adjacentVertax; 13 struct EageNode* nextAdjacentVer

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

图的广度度优先遍历算法运用队列主针对邻接表有向图

源代码如下: #include<iostream> using namespace std; #define MAX_VERTEX_NUM 20 typedef int EdgeData; typedef char VertexData; //顶点数据域 typedef struct node { // 边表节点 EdgeData cost; //边上d权值 int adjvex; //邻接点域 struct node *next; //下一边链接指针 }EdgeNode; typedef s