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]+"\t\t"); } 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]+"\t\t"); } 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