Prim算法
阿新 • • 發佈:2017-10-05
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 inti,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 intmin=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算法