图是一种很复杂的数据结构,为了描述图创造了邻接矩阵的方式来描述它,图和树不一样,构建图,首先必须要有节点,然而树的根节点可以为空,构建图需要先将图描述起来
1.图的节点个数
2.图的节点矩阵
3.图的邻接矩阵
构建一个图
/*
* 1.图的构成(顶点数量,顶点数组,顶点的邻接矩阵)
* 2.图的遍历
* 深度优先遍历和广度优先遍历
* 深度优先算法:类似于树的前序遍历,一个布尔型数组存储是否已经遍历过,然后根据第一个节点不断地寻找他的下一个邻接节点,找到它的下一个邻接节点后在将起始节点换为它的邻接节点的下一个节点
* 广度优先算法:类似于树的层序遍历,用一个队列来保存它的所有邻接节点,然后不断的根据他邻接节点的下一个节点来继续遍历它的下下个邻接节点
* 3.图的最小生成树,普林姆算法,克鲁斯卡尔算法,迪杰斯特拉算法
* 普林姆算法:精髓在于他有两个数组,一个数组用来存放当前情况下的最优解,然后根据当前情况下的最优数组找到最小值,置为0,遍历完及找到它的最优路径权值
* 克鲁斯卡尔算法:将图存放为,起始顶点 终止顶点 和权值的数组,通过不断删除回环路径来确定最优解
* 迪杰斯特拉算法:
*/
public class Graph{
private int verterSize;//顶点数量
private int[] verterArray;//顶点数组
private int[][] materix;//邻接矩阵
private boolean[] isvisited;
//private int[][] matrix;
public static final int MAX_WEIGHT=1000;
public int getVerterSize() {
return verterSize;
}
public void setVerterSize(int verterSize) {
this.verterSize = verterSize;
}
public int[] getVerterArray() {
return verterArray;
}
public void setVerterArray(int[] verterArray) {
this.verterArray = verterArray;
}
public int[][] getMaterix() {
return materix;
}
public void setMaterix(int[][] materix) {
this.materix = materix;
}
public boolean[] getIsvisited() {
return isvisited;
}
public void setIsvisited(boolean[] isvisited) {
this.isvisited = isvisited;
}
public static int getMaxWeight() {
return MAX_WEIGHT;
}
public Graph(int verterSize)
{
this.verterSize=verterSize;
this.verterArray=new int[verterSize];
this.materix=new int[verterSize][verterSize];
}
public void creatGraph()
{
this.verterSize=9;
this.verterArray= new int[]{0,1,2,3,4,5,6,7,8};
this.materix[0]=new int[] {0,10,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,11,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT};
//0,10,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,11,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT
this.materix[1]=new int[] {10,0,18,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,16,MAX_WEIGHT,12};
//10,0,18,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,16,MAX_WEIGHT,12
this.materix[2]=new int[] {MAX_WEIGHT,MAX_WEIGHT,0,22,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,8};
//MAX_WEIGHT,MAX_WEIGHT,0,22,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,8
this.materix[3]=new int[] {MAX_WEIGHT,MAX_WEIGHT,22,0,20,MAX_WEIGHT,MAX_WEIGHT,16,21};
//MAX_WEIGHT,MAX_WEIGHT,22,0,20,MAX_WEIGHT,MAX_WEIGHT,16,21
this.materix[4]=new int[] {MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,20,0,26,MAX_WEIGHT,7,MAX_WEIGHT};
//MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,20,0,26,MAX_WEIGHT,7,MAX_WEIGHT
this.materix[5]=new int[] {11,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,26,0,17,MAX_WEIGHT,MAX_WEIGHT};
//11,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,26,0,17,MAX_WEIGHT,MAX_WEIGHT
this.materix[6]=new int[] {MAX_WEIGHT,16,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,17,0,19,MAX_WEIGHT};
//MAX_WEIGHT,16,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,17,0,19,MAX_WEIGHT
this.materix[7]=new int[] {MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,16,7,MAX_WEIGHT,19,0,MAX_WEIGHT};
//MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,16,7,MAX_WEIGHT,19,0,MAX_WEIGHT
this.materix[8]=new int[] {MAX_WEIGHT,12,8,21,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,0};
//MAX_WEIGHT,12,8,21,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,0
}
图的深度优先遍历和广度优先遍历
//获取两个顶点之间的权值
public int getWeight(int pos1,int pos2)
{
return this.matrix[pos1][pos2];
}
//插入一个顶点
//删除一个顶点
//图的深度优先遍历
/*
* 获取某个顶点的第一个邻结点
* (给定一个index,通过index在矩阵中行遍历,返回它的第一个邻节点)
*/
//知道节点找他的第一个邻节点
public int getFirstNeighbor(int index)
{
for(int j=0;j0&&matrix[index][j]0&&matrix[v][j] queue=new LinkedList();
System.out.println("访问到:"+i+"顶点");
isvisited[i]=true;
queue.add(i);
while(!queue.isEmpty())
{
u=(Integer)(queue.removeFirst()).intValue();
w=getFirstNeighbor(u);
while(w!=-1)
{
System.out.println("访问到:"+w+"顶点");
isvisited[w]=true;
queue.addLast(w);
}
w=getNextNeighbor(u, w);
}
}
图的最小生成树算法(普林姆算法和克鲁斯卡尔算法)
//普林姆算法
//图的最小生成树
//普林母算法
public void prim()
{
int [] lowcost=new int[verterSize];//最小代价顶点权值的数组,为0表示已经找到
int [] adjvex=new int[verterSize];//放顶点权值
int min,minID,sum=0;
for(int i=1;i0)
{
min=lowcost[j];
minID=j;
}
}
System.out.println("顶点:"+adjvex[minID]+"权值"+min);//此时minID指向最小的那个位置
sum+=min;
lowcost[minID]=0;//将这个顶点置为零
for(int j=1;j
克鲁斯卡尔算法
public class GraphKruskal {
private Edge[] edges;
private int edgSize;
public GraphKruskal(int edgSize)
{
this.edgSize=edgSize;
this.edges=new Edge[edgSize];
}
class Edge
{
private int begin;
private int end;
private int weight;
public Edge(int begin,int end,int weight)
{
this.begin=begin;
this.end=end;
this.weight=weight;
}
}
public void creatEdgeArray()
{
Edge edge0=new Edge(4,7,7);
Edge edge1=new Edge(2,8,8);
Edge edge2=new Edge(0,1,10);
Edge edge3=new Edge(0,5,11);
Edge edge4=new Edge(1,8,12);
Edge edge5=new Edge(3,7,16);
Edge edge6=new Edge(1,6,16);
Edge edge7=new Edge(5,6,17);
Edge edge8=new Edge(1,2,18);
Edge edge9=new Edge(6,7,19);
Edge edge10=new Edge(3,4,20);
Edge edge11=new Edge(3,8,21);
Edge edge12=new Edge(2,3,22);
Edge edge13=new Edge(3,6,24);
Edge edge14=new Edge(4,5,26);
edges[0]=edge0;
edges[1]=edge1;
edges[2]=edge2;
edges[3]=edge3;
edges[4]=edge4;
edges[5]=edge5;
edges[6]=edge6;
edges[7]=edge7;
edges[8]=edge8;
edges[9]=edge9;
edges[10]=edge10;
edges[11]=edge11;
edges[12]=edge12;
edges[13]=edge13;
edges[14]=edge14;
}
public void miniSpanTreeKurskal()
{
int m,n,sum=0;
int[] parent=new int[edgSize];//以数组的下标为起点,值为终点
for(int i=0;i0)//当前位置有值
{
f=parent[f];
}
return f;
}
public static void main(String[] args)
{
GraphKruskal graphKruskal=new GraphKruskal(15);
graphKruskal.creatEdgeArray();
graphKruskal.miniSpanTreeKurskal();
}
}