- class Kruskal {
- public static int VERTS=6;
- public static int v[]=new int[VERTS+1];
- static K_Node NewList = new K_Node();
- public static void main(String[] args) {
- int Data[][] = /*圖形陣列宣告*/
- { {1,2,6},{1,6,12},{1,5,10},{2,3,3},{2,4,5},
- {2,6,8},{3,4,7},{4,5,9},{4,6,11},{5,6,1} };
- for(int i = 0 ; i < 10 ; i++ )
- NewList.Create(NewList.FindFree(),Data[i][2],Data[i][0],Data[i][1],0);
- NewList.printList();
- System.out.println("K氏法最小擴張樹");
- mintree() ;
- System.out.println("Prim法最小擴張樹");
- findmincost_prim() ;
- }
- //Prim法
- public static int U[]=new int[VERTS+1];//U集合
- public static int V[]=new int[VERTS+1];//V集合
- public static void findmincost_prim()
- {
- //u 已經有1個頂點
- int u = 1 ;
- int count = 1 ;
- int min = 999 , minv = 0 ;
- while(true){
- for(int v = 0 ; v <VERTS-1; v++){
- if(NewList.from[v] == u){
- if(V[NewList.to[v]] == 0 && min > NewList.val[v]){
- min = NewList.val[v] ;
- minv = v ;
- }
- }
- }
- if(count == u){//假設u數量等於count表全部檢查完
- System.out.print("起始頂點["+NewList.from[minv]+"] 終止頂點[");
- System.out.print(NewList.to[minv]+"] 路徑長度["+NewList.val[minv]+"]");
- System.out.println("");
- V[NewList.to[minv]] = 1;//V集合已加入倒U集合
- //U[NewList.to[minv]] = 1;
- count++ ;
- u = 1 ;//找出值後 u重製開開始重新判斷最小值
- min = 999 ; minv = 0 ;
- }else
- u++ ;
- if(count == U.length-1)//當U數量已飽和跟V一樣
- break ;
- }
- }
- //K氏法
- public static int findmincost()
- {
- int a=0;
- int minval=100;
- int retptr=0;
- while(NewList.Next[a] !=-1)
- {
- if(NewList.val[a]<minval && NewList.find[a]==0)
- {
- minval=NewList.val[a];
- retptr = a ;
- }
- a++ ;
- }
- NewList.find[retptr]=1;//設定已經用過
- return retptr;
- }
- public static void mintree(){
- int pointer = NewList.Header ;
- int retptr=0;//找出最小位置
- int a=0;
- while(pointer !=-1){ //走訪串列
- retptr = findmincost() ;
- v[NewList.from[retptr]]++ ; v[NewList.to[retptr]]++ ;
- if(v[NewList.from[retptr]] > 1 && v[NewList.to[retptr]] > 1){ //判斷會不會造成迴路
- v[NewList.from[retptr]]-- ; v[NewList.to[retptr]]-- ;
- }else{
- System.out.print("起始頂點["+NewList.from[retptr]+"] 終止頂點[");
- System.out.print(NewList.to[retptr]+"] 路徑長度["+NewList.val[retptr]+"]");
- System.out.println("");
- }
- pointer = NewList.Next[pointer];
- }
- }
- }
- class K_Node{
- int Header = 0 ; //起始
- int MaxLength = 20; // 定義鏈結串列最大長度
- int from[] = new int[MaxLength];// A
- int to[] = new int[MaxLength]; // B
- int find[] = new int[MaxLength];
- int val[] = new int[MaxLength]; //長度
- int Next[] = new int[MaxLength]; // 鏈結串列的下一個節點位置
- public K_Node () // Node建構子
- {
- for ( int i = 0 ; i < MaxLength ; i++ )
- Next[i] = -2; // -2表示未用節點
- }
- public void Create(int FreeNode,int DataNum,int fromNum,int toNum,int findNum){
- int pointer ; //現在的節點位置
- if(Header == FreeNode){
- val[Header] = DataNum ;
- from[Header] = fromNum ;
- to[Header] = toNum ;
- find[Header] = findNum ;
- Next[Header] = -1;
- }else{
- pointer = Header; // 現在的節點為首節點
- val[FreeNode] = DataNum;// 設定資料編號
- from[FreeNode]=fromNum;
- find[FreeNode]=findNum;
- to[FreeNode]=toNum;
- // 設定資料名稱
- Next[FreeNode] = -1; // 將下個節點的位置,-1表示空節點
- // 找尋鏈結串列尾端
- while ( Next[pointer] != -1)
- pointer = Next[pointer];
- // 將新節點串連在原串列尾端
- Next[pointer] = FreeNode;
- }
- }
- public int FindFree(){//搜尋可用節點
- int i ;
- for( i = 0; i < MaxLength ; i++){
- if( Next[i] == -2 )//未使用
- break ;
- }
- return i ;
- }
- public void printList(){
- int pointer = Header ;
- while(pointer != -1){
- System.out.println("邊線 : "+from[pointer] + "-->"+to[pointer]+" 長度 : "+val[pointer] );
- pointer = Next[pointer];
- }
- }
- }
2017年8月1日 星期二
(Java) K法與P法 求最小擴張樹
訂閱:
張貼留言 (Atom)


沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。