您的位置:首页 > 理论基础 > 数据结构算法

【数据结构】图的遍历

2015-09-03 22:58 323 查看
参考来自:深度优先搜索与广度优先搜索

参考来自:数据结构之图

自己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

;
labels = (E[]) new Object
;
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: