1、顺序表用于图的深度优先遍历
public class SeqList { public final int MaxSize = 10; public Object list[]; public int size; /** * 初始化 */ public SeqList() { list = new Object[MaxSize]; this.size = 0; } /* public SeqList initSeqList(SeqList seqList) { seqList.list = new Object[MaxSize]; seqList.size = 0; }*/ public boolean isFull(SeqList list) { if (list.size >= MaxSize) { return true; } return false; } public boolean isEmpty(SeqList list) { if (list.size <= 0) { return true; } return false; } public void insertList(SeqList seqList, int i, Object data) { if (isFull(seqList)) { System.out.println("已满无法插入"); return; } else if (i < 0 || i > seqList.size) { System.out.println("您输入的位置有问题"); return; } for (int j = seqList.size; j > i; j--) { seqList.list[j] = seqList.list[j - 1]; } seqList.list[i] = data; seqList.size++; } public void deleteList(SeqList seqList, int i) { if (isEmpty(seqList)) { System.out.println("已空,没有元素可删除"); return; } else if (i < 0 || i >= seqList.size) { System.out.println("您输入的位置参数有问题"); return; } for (int j = i+1; j <= seqList.size - 1; j++) { seqList.list[j-1] = seqList.list[j]; } seqList.size--; } public int getSize(SeqList seqList) { return seqList.size; } public Object getData(SeqList seqList, int i) { if (isEmpty(seqList)){ System.out.println("已空没有可取元素"); return null; }else if(i<0 || i>= seqList.size){ System.out.println("您给的位置有问题"); return null; } return seqList.list[i]; } public void printf(SeqList seqList) { if (isEmpty(seqList)){ System.out.println("已空,无需遍历"); return; } for (int i = 0; i < seqList.size; i++) { System.out.print(seqList.list[i] + " "); } } public static void main(String[] args) { SeqList seqList = new SeqList(); System.out.println("元素个数: "+ seqList.getSize(seqList)); seqList.printf(seqList); for (int i = 0; i < seqList.MaxSize; i++) { seqList.insertList(seqList,i,i); } seqList.deleteList(seqList,0); seqList.insertList(seqList,0,10); System.out.println("元素个数: "+ seqList.getSize(seqList)); seqList.printf(seqList); } }
2、创建顺序队列用户广度优先遍历
public class SeqQueue { public final int MaxSize = 8; public Object seqqueue[]; public int front; // 队头 public int rear; public int size; public SeqQueue() { this.size = 0; this.rear = 0; this.front = 0; this.seqqueue = new Object[MaxSize]; } public boolean isFull(SeqQueue seqQueue) { if (seqQueue.size > 0 && seqQueue.rear == seqQueue.front) { return true; } return false; } public boolean isEmpty(SeqQueue seqQueue) { if (seqQueue.size <= 0) { return true; } return false; } public void queueAppend(SeqQueue seqQueue, Object data) { if (isFull(seqQueue)) { System.out.println("已满无法插入"); return; } seqQueue.seqqueue[seqQueue.rear] = data; seqQueue.rear = (seqQueue.rear + 1) % MaxSize; seqQueue.size++; } public Object queueDelete(SeqQueue seqQueue) { if (isEmpty(seqQueue)) { System.out.println("已空"); return null; } Object x = seqQueue.seqqueue[seqQueue.front]; seqQueue.front = (seqQueue.front + 1) % MaxSize; seqQueue.size--; return x; } public static void main(String[] args) { SeqQueue seqQueue = new SeqQueue(); seqQueue.queueDelete(seqQueue); for (int i = 0; i < 9; i++) { seqQueue.queueAppend(seqQueue, i); } for (int i = 0; i < 8; i++) { System.out.println( seqQueue.queueDelete(seqQueue) + " "); ; } } }
3、创建需要插入的图信息类
public class CreateE { public int row; //行下标 public int col; //列下标 public int weight; // 权重 public CreateE() { } public CreateE(int row, int col, int weight) { this.row = row; this.col = col; this.weight = weight; } }
4、图的实现
/** * 图的邻接矩阵实现 * —— Wij (vi,vj)或<vi,vj> * | * aij = —— 无穷 i != j * | * —— 0 i = j */ public class Graph { public final int MaxWeight = 1000; //定义为无穷大(用于存储) public final int MaxVertices = 10; //顶点的最大值 SeqList vertices; //存放顶点的顺序表 int edge[][]; //存放边的邻接矩阵 int numberedge; //边的条数 public Graph() { edge = new int[MaxVertices][MaxVertices]; //初始化边的最大数组(这个和顺序表差不多) } /** * @param graph :要初始化的图 * @param n :给图分配几个顶点 */ public Graph initGraph(Graph graph, int n) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) { graph.edge[i][j] = 0; //对角线全为0 } else { graph.edge[i][j] = MaxWeight; //无穷大 } } } graph.numberedge = 0; //初始边条数0 graph.vertices = new SeqList(); //顶点顺序表初始化 return graph; } /** * 插入顶点 * * @param graph :需要插入顶点的图 * @param vertex :插入的顶点值 */ public void insertVertex(Graph graph, Object vertex) { graph.vertices.insertList(graph.vertices, graph.vertices.size, vertex); } /** * 插入边 * * @param graph : 需要插入边的图 * @param vi :边的一个顶点 * @param vj :边的另一顶点 * @param weight :边上的权重 */ public void insertEdge(Graph graph, int vi, int vj, int weight) { if (vi < 0 || vi >= graph.vertices.size || vj < 0 || vj >= graph.vertices.size) { System.out.println("参数vi,vj越界"); return; } graph.edge[vi][vj] = weight; graph.numberedge++; } /** * 删除边 * @param graph : 需要处理的图 * @param vi :顶点i * @param vj : 顶点j */ public void deleteEdge(Graph graph,int vi,int vj) { if (vi < 0 || vi >= graph.vertices.size || vj < 0 || vj >= graph.vertices.size) { System.out.println("参数vi,vj越界"); return; }else if(graph.edge[vi][vj] == MaxWeight || vi == vj){ System.out.println("边不存在"); return; } graph.edge[vi][vj] = MaxWeight; graph.numberedge--; } /** * 创建图 * @param graph :要创建的图 * @param V :顶点 * @param n :d顶点个数 * @param E :边 * @param e :边的个数 */ public void CreateGraph(Graph graph,Object V[],int n,CreateE E[],int e) { for (int i = 0; i < n; i++) { graph.insertVertex(graph,V[i]); } for (int i = 0; i < e; i++) { graph.insertEdge(graph,E[i].row,E[i].col,E[i].weight); } } /** * 获取图的边的条数 * @param graph : 需要操作的图 */ public void getNumberEdge(Graph graph) { if (graph == null){ System.out.println("该图不存在"); return; } System.out.println("边的条数: " + graph.numberedge); } /** * 取第一个邻接顶点 * @param graph :将要操作的图 * @param v : 某个顶点开始的第一个邻接顶点 * @return :找到返回邻接顶点下标,找不到反回-1,错误返回-1 */ public int getFirstVex(Graph graph, int v) { if (v < 0 || v >= graph.vertices.size) { System.out.println("获取第一个邻接顶点参数有问题"); return -1; } for (int col = 0; col < graph.vertices.size; col++) { if (graph.edge[v][col] > 0 && graph.edge[v][col] < MaxWeight){ //找到本顶点的二位数组中大与0小于无穷的第一个值,就是第一个邻接顶点 return col; } } return -1; } /** * 获取下一连接顶点 * @param graph :需要操作的图 * @param v1 :第一个顶点 * @param v2 :第一个顶点的邻接顶点 */ public int getNextVex(Graph graph,int v1,int v2) { if (v1 <0 || v1 >= graph.vertices.size || v2 <0 || v2 >= graph.vertices.size){ System.out.println("您要获取的下一邻接顶点参数有问题"); return -1; } for (int col = v2 + 1; col < graph.vertices.size; col++) { if (graph.edge[v1][col] >0 && graph.edge[v1][col] < MaxWeight){ return col; } } return -1; } /** * 连通图的深度优先遍历 * @param graph 需要操作的图 * @param v : 以某个顶点开始遍历 * @param visited :改点是否被访问 */ public void DepthSearch(Graph graph,int v,int visited[]) { System.out.print(graph.vertices.list[v] + " "); //先打印第一个访问的顶点 visited[v] = 1 ; //让改点为已经访问过 1 :访问过 0 : 未访问 int col = graph.getFirstVex(graph,v); //获取访问顶点的下一顶点 while (col != -1){ //如果该节点存在 if (visited[col] == 0){ graph.DepthSearch(graph,col,visited); } col = graph.getNextVex(graph,v,col); } } /** * 非连通图的深度优先遍历 */ public void DepthFirstSearch(Graph graph) { int visited[] = new int[graph.vertices.size]; for (int i = 0; i < graph.vertices.size; i++) { visited[i] = 0; //未访问标记初始值为0 } for (int i = 0; i < graph.vertices.size; i++) { if (visited[i] == 0){ graph.DepthSearch(graph,i,visited); } } } /** * 连通图的广度优先遍历 * @param graph * @param v * @param visited */ public void BroadSearch(Graph graph,int v,int visited[]) { SeqQueue seqQueue = new SeqQueue(); System.out.print(graph.vertices.list[v]+" "); visited[v] = 1; seqQueue.queueAppend(seqQueue,v); //初始顶点入队 while (!seqQueue.isEmpty(seqQueue)){ //队列未空 int n = (int)seqQueue.queueDelete(seqQueue); int col = graph.getFirstVex(graph,n); while (col != -1){ if (visited[col] == 0){ System.out.print(graph.vertices.list[col] + " "); visited[col] = 1; //设为已访问 seqQueue.queueAppend(seqQueue,col); //邻接顶点入队 } col = graph.getNextVex(graph,n,col); } } } public void BroadFirstSearch(Graph graph) { int visited[] = new int[graph.vertices.size]; for (int i = 0; i < graph.vertices.size; i++) { visited[i] = 0; //访问标记初始为0 } for (int i = 0; i < graph.vertices.size; i++) { if (visited[i] == 0){ BroadSearch(graph,i,visited); } } } public static void main(String[] args) { Graph graph = new Graph(); int n = 6,e=6; graph.initGraph(graph,n); Object V[] = {'A','B','C','D','E','F'}; CreateE E[] = {new CreateE(0,1,10),new CreateE(0,4,20),new CreateE(1,3,30),new CreateE(2,1,40),new CreateE(3,2,50),new CreateE(0,5,30)}; graph.CreateGraph(graph,V,n,E,e); System.out.print("顶点集合:"); for (int i = 0; i < graph.vertices.size; i++) { System.out.print(graph.vertices.list[i]+ " "); } System.out.println(); System.out.println("权值集合"); for (int i = 0; i < graph.vertices.size; i++) { for (int j = 0; j < graph.vertices.size; j++) { System.out.print(graph.edge[i][j]+" "); } System.out.println(); } graph.getNumberEdge(graph); System.out.println("取第一个邻接顶点 : " + graph.vertices.list[graph.getFirstVex(graph,0)]); //这里取不到就会报错哦。因为取不到,我这设置返回-1 System.out.println("取下一个邻接顶点 : " +graph.vertices.list[graph.getNextVex(graph,0,graph.getFirstVex(graph,0))]); System.out.print("图的深度优先遍历 :"); graph.DepthFirstSearch(graph); System.out.println(); System.out.print("图的广度优先遍历 :"); graph.BroadFirstSearch(graph); System.out.println(); graph.deleteEdge(graph,0,1); graph.getNumberEdge(graph); System.out.println("权值集合"); for (int i = 0; i < graph.vertices.size; i++) { for (int j = 0; j < graph.vertices.size; j++) { System.out.print(graph.edge[i][j]+" "); } System.out.println(); } } }
5、实现结果
顶点集合:A B C D E F 权值集合 0 10 1000 1000 20 30 1000 0 1000 30 1000 1000 1000 40 0 1000 1000 1000 1000 1000 50 0 1000 1000 1000 1000 1000 1000 0 1000 1000 1000 1000 1000 1000 0 边的条数: 6 取第一个邻接顶点 : B 取下一个邻接顶点 : E 图的深度优先遍历 :A B D C E F 图的广度优先遍历 :A B E F D C 边的条数: 5 权值集合 0 1000 1000 1000 20 30 1000 0 1000 30 1000 1000 1000 40 0 1000 1000 1000 1000 1000 50 0 1000 1000 1000 1000 1000 1000 0 1000 1000 1000 1000 1000 1000 0