1. 程式人生 > >Prim算法

Prim算法

arc flush += java知識點 next 讀取 路徑 index buffered

今天學習了prim算法。嚴奶奶的代碼我沒看懂,畢竟她都80歲了。算了,我自己按照書上的描述寫了一個。

今天學習的Java知識點:調用類中的類進行變量聲明可以使用 className.innerClassName objectName 這種聲明方式。

解題所用數據結構:鄰接矩陣。

可視化:

技術分享

鄰接矩陣prim.txt:(-1代表

-1 6 1 5 -1 -1
6 -1 5 -1 3 -1
1 5 -1 5 6 4
5 -1 5 -1 -1 2
-1 3 6 -1 -1 6
-1 -1 4 2 6 -1

解題代碼:(Java)

 1     void prim(){
 2         int
i,j; 3 List<Integer> V=new ArrayList<Integer>();//集合V 4 List<Integer> U=new ArrayList<Integer>();//集合U 5 for(i=1;i<vexnum;i++) V.add(i); //V初始化 6 U.add(0); //U初始化 7 while(V.size()>0){ 8 int
min=10000; 9 int a=0;//源點 10 int b=0;//目標點 11 for(i=0;i<U.size();i++){//取出U中每一個元素 12 int u=U.get(i);//每一次取出的元素 13 for(j=0;j<V.size();j++){//j 14 int v=V.get(j); 15 int value=adjMatrix[u][v];//取出的元素 16 if
(value!=-1 && value<min){ 17 min=value; 18 a=u; 19 b=v; 20 } 21 } 22 } 23 U.add(b); 24 V.remove(V.indexOf(b)); 25 System.out.println(a+"->"+b); 26 } 27 }

輸出:

0->2
2->5
5->3
2->1
1->4

今天編寫的完整代碼:(Java)

  1 import java.io.*;
  2 import java.util.*;
  3 
  4 public class demo {
  5     public static void main(String args[]){
  6         Graph grath=new Graph("D:/JavaWorkspace/圖狀結構/prim.txt");
  7         System.out.println("鄰接矩陣:");
  8         System.out.println(grath);
  9         System.out.println("鄰接鏈表:");
 10         System.out.println(grath.getListStr());
 11         System.out.println("最小生成樹:");
 12         grath.prim();
 13     }
 14 }
 15 
 16 class Graph{
 17     int [][] adjMatrix;//adjacency matrix 鄰接矩陣數據結構
 18     int vexnum=0;        //頂點數目
 19     AdjList adjList=null;
 20     class AdjList{        //鄰接表
 21         class VNode{    //頂點節點。頭節點
 22             int index=0;//頂點編號
 23             ANode firstArc=null;//第一個弧節點
 24         }
 25         class ANode{            //弧節點
 26             int adjVex=0;        //所指向頂點位置
 27             ANode nextArc=null;    //下一條弧
 28         }
 29         VNode vnodes[]=null;
 30         AdjList(){
 31         }
 32         AdjList(int [][] nums,int v){//用二維數組進行構造
 33             vnodes=new VNode[v];
 34             int i,j;
 35             for(i=0;i<v;i++){
 36                 vnodes[i]=new VNode();
 37                 vnodes[i].index=i+1;//頂點數組初始化
 38             }
 39             for(i=0;i<v;i++){
 40                 for(j=0;j<v;j++){            //對鄰接矩陣進行遍歷
 41                     if(nums[i][j]!=-1){        //有元素
 42                         ANode arc=new ANode();
 43                         arc.adjVex=j;
 44                         if(vnodes[i].firstArc==null) vnodes[i].firstArc=arc;
 45                         else{
 46                             ANode node=vnodes[i].firstArc;
 47                             while(node.nextArc!=null) node=node.nextArc;
 48                             node.nextArc=arc;        //勾鏈
 49                         }
 50                     }
 51                 }
 52             }
 53         }
 54     }
 55     String getListStr(){//打印鄰接鏈表
 56         int i;
 57         String str=new String();
 58         for(i=0;i<vexnum;i++){
 59             str+=Integer.toString(adjList.vnodes[i].index);
 60             str+=":";
 61             AdjList.ANode node=adjList.vnodes[i].firstArc;
 62             while(node!=null){
 63                 str+=Integer.toString(node.adjVex);
 64                 str+="->";
 65                 node=node.nextArc;
 66             }
 67             str+="∧\n";
 68         }
 69         return str;
 70     }
 71     public String toString(){
 72         String str=new String();
 73         int i,j;
 74         for(i=0;i<vexnum;i++){
 75             for(j=0;j<vexnum;j++){            //對鄰接矩陣進行遍歷
 76                 str+=Integer.toString(adjMatrix[i][j]);
 77                 str+=" ";
 78             }
 79             str+="\n";
 80         }
 81         return str;
 82     }
 83     Graph(String path){//通過文件路徑,輸入文件來讀取鄰接矩陣
 84         String content=MyFile.readFile(path);//讀取文件內容
 85         String lines[]=content.split("\n");
 86         String probe[];
 87         vexnum=lines.length;
 88         adjMatrix=new int[vexnum][vexnum];//刻畫鄰接矩陣大小
 89         
 90         int i,j;
 91         for(i=0;i<lines.length;i++){
 92             probe=lines[i].split(" ");
 93             for(j=0;j<probe.length;j++){
 94                 adjMatrix[i][j]=Integer.valueOf(probe[j]).intValue();//要對integer進行拆包
 95             }
 96         }
 97         adjList=new AdjList(adjMatrix,lines.length);//構造本類中的鄰接鏈表
 98     }
 99 /*        class CloseEdge{        //記錄 U-V 中各頂點到 U 中權值最小的邊
100             int adjvex=0;    //邊所依附於 U 中的頂點
101             int lowcost=0;    //這條邊的權值(代價最小)
102         }
103         CloseEdge closedge[]=new CloseEdge[vexnum];//構建數組
104 */        
105     void prim(){
106         int i,j;
107         List<Integer> V=new ArrayList<Integer>();//集合V
108         List<Integer> U=new ArrayList<Integer>();//集合U
109         for(i=1;i<vexnum;i++) V.add(i);            //V初始化
110         U.add(0);                                //U初始化
111         while(V.size()>0){
112             int min=10000;
113             int a=0;//源點
114             int b=0;//目標點
115             for(i=0;i<U.size();i++){//取出U中每一個元素
116                 int u=U.get(i);//每一次取出的元素
117                 for(j=0;j<V.size();j++){//j
118                     int v=V.get(j);
119                     int value=adjMatrix[u][v];//取出的元素
120                     if(value!=-1 && value<min){
121                         min=value;
122                         a=u;
123                         b=v;
124                     }
125                 }
126             }
127             U.add(b);
128             V.remove(V.indexOf(b));
129             System.out.println(a+"->"+b);
130         }
131     }
132     private boolean findInNum(int[] arr,int obj){
133         for(int i=0;i<arr.length;i++) if(arr[i]==obj) return true;
134         return false;
135     }
136     
137     
138 }
139 
140 class MyFile{
141 
142     /**
143      * 創建文件
144      * @param fileName  文件名稱
145      * @param filecontent   文件內容
146      * @return  是否創建成功,成功則返回true
147      */
148     public static boolean createFile(String fileName){
149         boolean bool = false;
150         File file = new File(fileName);
151         try {
152             //如果文件不存在,則創建新的文件
153             if(!file.exists()){
154                 file.createNewFile();
155                 bool = true;
156                 System.out.println("success create file,the file is "+fileName);
157             }
158         } catch (Exception e) {
159             e.printStackTrace();
160         }
161         return bool;
162     }
163     
164     /**
165      * 向文件中寫入內容
166      * @param filepath 文件路徑與名稱
167      * @param newstr  寫入的內容
168      * @return
169      * @throws IOException
170      */
171     public static boolean writeFile(String filepath,String newstr) throws IOException{
172         boolean bool = false;
173         String filein = newstr+"\r\n";//新寫入的行,換行
174         String temp  = "";
175         
176         FileInputStream fis = null;
177         InputStreamReader isr = null;
178         BufferedReader br = null;
179         FileOutputStream fos  = null;
180         PrintWriter pw = null;
181         try {
182             File file = new File(filepath);//文件路徑(包括文件名稱)
183             //將文件讀入輸入流
184             fis = new FileInputStream(file);
185             isr = new InputStreamReader(fis);
186             br = new BufferedReader(isr);
187             StringBuffer buffer = new StringBuffer();
188             
189             //文件原有內容
190             for(int i=0;(temp =br.readLine())!=null;i++){
191                 buffer.append(temp);
192                 // 行與行之間的分隔符 相當於“\n”
193                 buffer = buffer.append(System.getProperty("line.separator"));
194             }
195             buffer.append(filein);
196             
197             fos = new FileOutputStream(file);
198             pw = new PrintWriter(fos);
199             pw.write(buffer.toString().toCharArray());
200             pw.flush();
201             bool = true;
202         } catch (Exception e) {
203             // TODO: handle exception
204             e.printStackTrace();
205         }finally {
206             //不要忘記關閉
207             if (pw != null) {
208                 pw.close();
209             }
210             if (fos != null) {
211                 fos.close();
212             }
213             if (br != null) {
214                 br.close();
215             }
216             if (isr != null) {
217                 isr.close();
218             }
219             if (fis != null) {
220                 fis.close();
221             }
222         }
223         return bool;
224     }
225  
226     /**
227      * 刪除文件
228      * @param fileName 文件名稱
229      * @return
230      */
231     public static boolean delFile(String fileName){
232         boolean bool = false;
233         File file  = new File(fileName);
234         try {
235             if(file.exists()){
236                 file.delete();
237                 bool = true;
238             }
239         } catch (Exception e) {
240             // TODO: handle exception
241         }
242         return bool;
243     }
244     public static String readFile(String fileName) {
245         File file = new File(fileName);
246         Reader reader = null;
247         String content=new String();
248         try {
249             // 一次讀一個字符
250             reader = new InputStreamReader(new FileInputStream(file));
251             int tempchar;
252             while ((tempchar = reader.read()) != -1) {
253                 // 對於windows下,\r\n這兩個字符在一起時,表示一個換行。
254                 // 但如果這兩個字符分開顯示時,會換兩次行。
255                 // 因此,屏蔽掉\r,或者屏蔽\n。否則,將會多出很多空行。
256                 if (((char) tempchar) != ‘\r‘) {
257                  //   System.out.print((char) tempchar);
258                     content+=((char) tempchar);
259                 }
260             }
261             reader.close();
262         } catch (Exception e) {
263             e.printStackTrace();
264         }
265         return content;
266     }
267 }

Prim算法