【数据结构】图的遍历

参考来自:深度优先搜索与广度优先搜索

参考来自:数据结构之图

自己JAVA实现代码如下:

package graphs;

import java.util.LinkedList;
import java.util.Queue;

public class Graph<E> implements Cloneable
{
	private boolean[][] edges;
	private E[] labels;
	
	public Graph (int n)
	{
		edges = new boolean[n][n];
		labels = (E[]) new Object[n];
		int i,j;
		
		for (i = 0; i < n; i++)
			for (j = 0; j < n; j++)
			{
				edges[i][j] = false;
			}
	}
	
	// 增加一条边
	public void addEdge(int source, int target)
	{
		edges[source][target] = true;
	}
	
	// 测试一条边是否存在
	public boolean isEdge(int source, int target)
	{
		return edges[source][target];
	}
	
	// 删除该Graph的一条边
	public void removeEdge(int source, int target)
	{
		edges[source][target] = false;
	}

	// 生成一个该Graph的副本
	public Graph<E> clone()
	{
		Graph<E> answer;
		
		try
		{
			answer = (Graph<E>) super.clone();
		} catch (Exception e)
		{
			throw new RuntimeException("This class does not implement Cloneable");
		}
		
		answer.edges = edges.clone();
		answer.labels = labels.clone();
		
		return answer;
	}
	
	// 用于获取该Graph的某个顶点标签
	public E getlabel(int vertex)
	{
		return labels[vertex];
	}
	
	// 改变该Graph的顶点标签
	public void setLabel(int vertex, E newLabel)
	{
		labels[vertex] = newLabel;
	}
	
	// 用于获取该graph中指定顶点的邻接点列表
	public int[] neighbors(int vartex)
	{
		int i;
		int count;
		int[] answer;
		
		count = 0;
		// 首先计算有多少条边以该顶点为起点
		for (i = 0; i < labels.length; i++)
		{
			if (edges[vartex][i])
			{
				count++;
			}
		}
		
		answer = new int[count];
		
		count = 0;
		for (i = 0; i < labels.length; i++)
		{
			if (edges[vartex][i])
			{
				answer[count++] = i;
			}
		}
		
		return answer;
	}
	
	// 表示确定该Graph中顶点的数目
	public int size()
	{
		return labels.length;
	}
	
	/**
	 * 图的遍历,深度优先查找算法
	 * @param g    非Null的图
	 * @param start  Graph 中的一个顶点编号
	 */
	public static<E> void depthFirstPrint(Graph<E> g, int start)
	{
		boolean[] marked = new boolean[g.size()];
		depthFirstRecurse(g, start, marked);
	}
	
	/**
	 * 递归调用
	 * @param g  要遍历的图
	 * @param v  g中的顶点编号
	 * @param marked 一个用于标记g中哪个顶点已经访问过了的数值
	 */
	public static <E> void depthFirstRecurse(Graph<E> g, int v, boolean[] marked)
	{
		int[] connections = g.neighbors(v);
		
		marked[v] = true;
		System.out.println(g.getlabel(v));
		
		// 遍历所有的邻接点,查找未标记的顶点
		for (int nextNeighbor:connections)
		{
			if (!marked[nextNeighbor])
			{
				depthFirstRecurse(g, nextNeighbor, marked);
			}
		}
	}
	
	// 广度优先查找算法
	public void scopeFirstPrint(Graph<E> g)
	{
		boolean[] marked = new boolean[g.size()];
		Queue<Integer> queue = new LinkedList<Integer>();
		
		queue.add(0);
		marked[0] = true;
		System.out.println(g.getlabel(0));
		
		int v1,v2;
		while (!queue.isEmpty())
		{
			v1 = queue.remove();
			while ((v2 = getAdjUnvisitedVertex(v1, marked)) != -1)
			{
				marked[v2] = true;
				System.out.println(g.getlabel(v2));
				queue.add(v2);
			}
		}
	}
	
	// 得到这个顶点没有被访问的邻居点
	public int getAdjUnvisitedVertex(int vertex, boolean[] marked)
	{
		for (int i = 0; i < marked.length; i++)
		{
			if (edges[vertex][i] && !marked[i])
			{
				return i;
			}
		}
		return -1;
	}
	
	
	public static void main(String[] args)
	{
		Graph<Integer> graph = new Graph<Integer>(7);
		graph.addEdge(0, 1);
		graph.addEdge(0, 4);
		graph.addEdge(1, 3);
		graph.addEdge(3, 0);
		graph.addEdge(2, 0);
		graph.addEdge(6, 1);
		graph.addEdge(3, 6);
		graph.addEdge(3, 5);
		
		for (int i = 0; i < graph.size(); i++)
		{
			graph.setLabel(i, i);
		}
		
		// 递归 深度搜索
  	    Graph.depthFirstPrint(graph, 0);
  	    
  	    // 广度搜索算法
		//graph.scopeFirstPrint(graph);
	}
}

结果是:

0
1
3
5
6
4


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值