Prim算法

今天学习了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 }

 程序完成输出:

邻接矩阵:
-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

邻接链表:
1:1->2->3->∧
2:0->2->4->∧
3:0->1->3->4->5->∧
4:0->2->5->∧
5:1->2->5->∧
6:2->3->4->∧

最小生成树:
0->2
2->5
5->3
2->1
1->4

posted @ 2017-10-04 22:10  TQCAI  阅读(1244)  评论(0编辑  收藏  举报