在图的邻接表的存储下进行的深度优先遍历:需要用到哈希表来辅助。
具体的实现代码如下:
package com.threeTop.www;
/**
* 邻接表节点的定义
* @author wjgs
*
*/
public class ListGraphNode {
//增加索引
int index;
//值
int value;
//指向下一个节点的指针(引用)
ListGraphNode next;
//构造函数实现初始化
public ListGraphNode(int value,ListGraphNode next)
{
this.value=value;
this.next=next;
}
//构造函数实现初始化
public ListGraphNode(int index,int value,ListGraphNode next)
{
this.index=index;
this.value=value;
this.next=next;
}
}
package com.threeTop.www;
import java.util.Hashtable;
import java.util.Stack;
/**
* 图的邻接表的实现
* @author wjgs
*
*/
public class ListGraph {
//图的顶点数组
private ListGraphNode []nodes;
//借助的哈希表
private Hashtable<Integer,Integer> valueindex=new Hashtable<Integer,Integer>();
/**
* 初始化图的顶点
* @param vertexes
*/
public ListGraph(int []vetexes)
{
nodes=new ListGraphNode[vetexes.length];
for(int i=0;i<vetexes.length;i++)
{
//初始化每个节点
nodes[i]=new ListGraphNode(i,vetexes[i],null);
//hash记录每个位置
valueindex.put(vetexes[i], i);
}
}
/**
* 添加start可达到的边
* @param start
* @param end
*/
public void addEdge(int start ,int []end)
{
for(int i=0;i<nodes.length;i++)
{
if(nodes[i].value==start)
{
ListGraphNode node=nodes[i];
//内部数组的遍历,添加到一个邻接表
for(int j=0;j<end.length;j++)
{
node.next=new ListGraphNode(end[j],null);
node=node.next; //链接下一个
}
}
}
}
/**
* 添加start可达到的边
* @param start
* @param end
*/
public void addEdges(int start ,int []end)
{
int index=valueindex.get(start);
if(index<0)
{
throw new RuntimeException("未找到指定的起始顶点");
}
ListGraphNode node=nodes[index];
for(int j=0;j<end.length;j++)
{
int i=valueindex.get(end[j]);
if(i<0)
{
throw new RuntimeException("未找到指定的起始顶点");
}
node.next=new ListGraphNode(i,end[j],null);
node=node.next; //链接下一个
}
}
/**
* 打印邻接表的数据
*
*/
public void printListGraph()
{
System.out.println("输出图的邻接矩阵存储为:");
for(int i=0;i<nodes.length;i++)
{
ListGraphNode node=nodes[i];
do
{
System.out.print(node.value);
node=node.next;
}while(node!=null);
//换行操作
System.out.println();
}
}
/**
*
* 邻接表深度优先遍历
*/
public void depthFirstTravel()
{
System.out.println("邻接表深度优先遍历为:");
//初始化栈
Stack <Integer>stack=new Stack<Integer>();
//初始化各顶点的访问状态
int[] visited=new int[nodes.length];
//从未访问顶点中任选一个顶点作为起始顶点
int unvisited=getUnvisited(visited);
while(unvisited>=0)
{
visited[unvisited]=1;
//压入栈
stack.push(unvisited);
//输出访问的节点
System.out.print(nodes[unvisited].value+" ");
//栈非空
while(!stack.isEmpty())
{
//获取栈顶的元素,不出栈
int index=stack.peek();
//遍历找到未被访问的邻接顶点
boolean found=false;
//获得栈顶的节点
ListGraphNode node=nodes[index];
while(node!=null)
{
//节点的下一个节点没有被访问过
if(node.next!=null&&visited[node.next.index]==0)
{
//如果找到则访问入栈
visited[node.next.index]=1;
stack.push(node.next.index);
//输出遍历到的元素
System.out.print(node.next.value+" ");
found=true;
break;
}
//寻找下一个节点
node=node.next;
}
if(!found)
{
//弹出栈顶的元素
stack.pop();
}
}
unvisited=getUnvisited(visited);
}
System.out.println();
}
/**
* 从访问标记数组中获取第1个发现的未被访问的顶点下标
* @param visited
* @return 若都被访问了,就返回-1
*/
private int getUnvisited(int[] visited) {
int index=-1;
for(int i=0;i<visited.length;i++)
{
//i节点没有被访问
if(visited[i]==0)
{
index=i;
break;
}
}
return index;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] vetexes={0,1,2,3,4,5,6,7};
ListGraph graph=new ListGraph(vetexes);
graph.addEdge(0, new int []{1,2});
graph.addEdge(1, new int[]{3,4});
graph.addEdge(2, new int[]{5,6});
graph.addEdge(3, new int[]{7});
graph.addEdge(4, new int[]{7});
graph.addEdge(5, new int[]{7});
graph.addEdge(6, new int[]{7});
graph.printListGraph();
graph.depthFirstTravel();
}
}