其次,还是先上代码吧,后续有时间在介绍一下算法。
顶点类:
package graph;
/**
* 顶点类
* @author Administrator
*
*/
public class Vertex {
private char label;
private boolean wasVisit;
public Vertex(char label){
this.label = label;
}
public char getLabel() {
return label;
}
public void setLabel(char label) {
this.label = label;
}
public boolean isWasVisit() {
return wasVisit;
}
public void setWasVisit(boolean wasVisit) {
this.wasVisit = wasVisit;
}
}
图类
package graph;
import stack_queue.MyStack;
/**
* 图
* @author Administrator
*
*/
public class Graph {
//顶点数组
private Vertex[] vertexList;
//邻接矩阵
private int[][] adjMat;
//顶点最大数目
private int maxsize;
//已添加的顶点
private int nVertex;
private MyStack stack;
/**
* 构造方法
* @param maxsize
*/
public Graph(int maxsize){
vertexList = new Vertex[maxsize];
adjMat = new int[maxsize][maxsize];
for(int i=0;i<maxsize;i++){
for(int j=0;j<maxsize;j++){
adjMat[i][j] = 0;
}
}
nVertex = 0;
stack = new MyStack(100);
}
/**
* 添加顶点
* @param label
*/
public void addVertex(char label){
vertexList[nVertex++] = new Vertex(label);
}
/**
* 添加边
* @param start
* @param end
*/
public void addEdge(int start,int end){
adjMat[start][end] = 1;
adjMat[end][start] = 1;
}
/**
* 找到邻接的但是没有访问过的顶点
* @param v 找哪个的邻接没有访问过的顶点
* @return 返回顶点,返回-1 则找不到
*/
public int getAdjUnvisited(int v){
for(int i=0; i<nVertex; i++){
if(adjMat[v][i] == 1 && vertexList[i].isWasVisit() == false){
return i;
}
}
return -1;
}
/**
* 深度搜索
*/
public void dfs(){
//首先访问0号顶点
vertexList[0].setWasVisit(true);
display(0);
//入栈
stack.push(0);
while(!stack.isEmpty()){
//获得未访问过的邻接顶点
int v = getAdjUnvisited((int)stack.peek());
if(v == -1){
//弹出顶点
stack.pop();
}else{
vertexList[v].setWasVisit(true);
display(v);
stack.push(v);
}
}
//搜索完成后,要将访问信息修改
for(int i=0;i<nVertex; i++){
vertexList[i].setWasVisit(false);
}
}
/**
* 显示该顶点
* @param v 顶点
*/
public void display(int v){
System.out.print(vertexList[v].getLabel());
}
}
上面再做图的搜索中只是用到了深度搜索,当然还有广度搜索,这里没有给出,以后补充进来。
上面做深度搜索的时候用到了栈,借用前几天写的栈代码就可以了,这里贴出来吧。
package stack_queue;
public class MyStack {
private long [] arr;
private int top;
public MyStack(){
arr = new long[10];
top = -1;
}
public MyStack(int maxsize){
arr = new long[maxsize];
top = -1 ;
}
/**
* 入栈
*/
public void push(int value){
arr[++top] = value;
}
/**
* 出栈
*/
public long pop(){
return arr[top--];
}
/**
* 查看数据
*/
public long peek(){
if(top != -1){
return arr[top];
}else return 0;
}
/**
* 判断是否为空
*/
public boolean isEmpty(){
return top == -1;
}
/**
* 判断是否满了
*/
public boolean isFull(){
return top == arr.length-1;
}
}
测试类
package graph;
public class TestGraph {
public static void main(String[] args) {
Graph g = new Graph(100);
g.addVertex('A');
g.addVertex('B');
g.addVertex('C');
g.addVertex('D');
g.addVertex('E');
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(2, 4);
g.dfs();
}
}
图的最小生成树:
连接每个顶点最小的连线,最小生成树边的数量总是比顶点少1。
/**
* 最小生成树
*/
public void mst(){
//首先访问0号顶点
vertexList[0].setWasVisit(true);
//入栈
stack.push(0);
while(!stack.isEmpty()){
//获得当前节点
int currentVertex = (int)stack.peek();
//获得未访问过的邻接顶点
int v = getAdjUnvisited((int)stack.peek());
if(v == -1){
//弹出顶点
stack.pop();
}else{
vertexList[v].setWasVisit(true);
stack.push(v);
display(currentVertex);
System.out.print("-");
display(v);
System.out.print(" ");
}
}
//搜索完成后,要将访问信息修改
for(int i=0;i<nVertex; i++){
vertexList[i].setWasVisit(false);
}
}