1. 程式人生 > >Java連結串列實現儲存一個隨機圖

Java連結串列實現儲存一個隨機圖

  1. 演算法老師佈置的一個小作業,在大哥的點撥下完成了這個實現,也是對Java連結串列的一種熟悉。如有不正確之處還請各位大神指教!
  2. 要求:生成一個隨機圖,(原則上是上限50個點,100條邊),用連結串列進行儲存,本次試驗的結果作為下次試驗的素材。
  3. 首先,自己是一個小白,對於連結串列只是只聞其名,不知其理,搞完這個之後,對於連結串列的結構以及用法都有了進一步的瞭解。實現這個功能的最主要之處就是弄清楚整個圖儲存方式的大體架構和各個資料結構變數屬性之間的層次關係。
  4. 言歸正傳:
    首先要了解一下Java中的連結串列類linkedList,是Java.util包下的一個類,大家可以下載一個JavaAPI去檢視一下該類的具體建構函式和呼叫方法。

    下載中文版JavaAPI點選此處
    實現的主要過程:建立一個連結串列型別的陣列point[],陣列的每一個元素都是一個連結串列,並且每個連結串列元素又是Node類的一個物件,弄清楚這個層次關係是實現的關鍵。
    下邊就是具體的程式碼實現了:
    (1)建立Node類,用於儲存圖一條邊的末節點(endPoint)還有權重(weight),還有其相應的構造方法。
    這裡寫圖片描述

    (2)建立Random_Graph類的構造方法:
    這裡寫圖片描述
    A:首先LinkedList類和Random類都在Java.util 包中,所以import java.util.*;
    B:然後定義一個ListedList型別的陣列point,在構造方法中例項化為new LinkedList[numPoint];
    這就類似於定義一個int型別陣列:int [] arr =new int [32];
    C: Random_Graph類的構造方法中各個引數的意義:
    numPoint:圖節點的數目;
    numEdge:圖邊的數目;
    has_director:圖為有向圖(有向圖一條邊只需要儲存一次,無向圖一條邊儲存兩次);
    has_weight : 圖為有權重的圖(無權重的圖預設權重為1)。
    D:通過一個for迴圈將陣列point初始化賦值
    關於在定義陣列和初始化陣列的時候加上一個“《Node》”,目的是使陣列元素為Node型別,以便於實現endPoint和weight屬性。官方化的解釋見JavaAPI中LinkedList的構造方法:
    這裡寫圖片描述

(3)新增一條邊的前提以及需要注意的事項:
這裡寫圖片描述
A:首先隨機生成一條邊的起始點(startPoint)和終止點(endPoint);
B:一條邊的起始點和終止點為同一個點,則該邊為一個自環,應該避免這種現象;
C:如果一條邊已經建立了,那麼就跳出該迴圈。(起始點和終止點相同的邊視為同等邊)

(4)判斷是否有權重,是否為有向圖,把邊加到連結串列中
這裡寫圖片描述
A :預設權重為1,如果存在權重,隨機生成一個權重(範圍為1-9);
B:判斷是否為有向圖,無向圖需要新增兩次。
這個地方用到了連結串列的庫函式:add();引數型別是Node型別。
至此構造方法已經完畢。

下邊再構造一個print方法:遍歷打印出圖的首節點和末尾節點以及權重。
這裡寫圖片描述

main方法實現以下:
這裡寫圖片描述

執行結果:
這裡寫圖片描述
無向圖對應的節點和相應的權重,同一條邊新增兩次的對應形式。

原始碼如下:

package algorithm;
import java.util.*;

public class Random_Graph {
    LinkedList<Node> []point;
    public Random_Graph(int numPoint,int numEdge,boolean has_director,boolean has_weight){
        point =new LinkedList[numPoint];

        for(int i=0;i<numPoint;i++){
            point[i]=new LinkedList<Node>();
        }
//      隨機生成起始點和終止點
        while (numEdge>0){
            Random r=new Random();
            int startPoint=r.nextInt(numPoint);
            int endPoint=r.nextInt(numPoint);

//          如果起始點等於終止點,那麼就在一點生成一條環,去除這種情況
            while(startPoint==endPoint){
                endPoint=r.nextInt(numPoint);
            }

//          如果這條邊已經有了,那麼就跳過該次迴圈         
            boolean has_edge=false;
            for(int j=0;j<point[startPoint].size();j++){
                if(point[startPoint].get(j).endpoint==endPoint){
                    has_edge=true;
                    break;
                }
            }
            if(has_edge){
                continue;
            }

//          如果有權重,加上隨機生成的權重,否則預設為1
            int weight=1;
            if(has_weight){
                weight=r.nextInt(9)+1;
            }
//          如果是無向圖,那麼一條邊需要加兩次
            if(has_director){
                point[startPoint].add(new Node(weight,endPoint));
            }
            else{
                point[startPoint].add(new Node(weight,endPoint));
                point[endPoint].add(new Node (weight,startPoint));
            }



            numEdge--;
        }
    }
    public void print_Graph(){
        for(int i=0;i<point.length;i++){
            System.out.print("the start_point is: "+i);
            for(int j=0;j<point[i].size();j++){
                System.out.print("   "+point[i].get(j).endpoint+"  ("+point[i].get(j).weight+")");
            }
            System.out.println();
        }
    }
    public static void main(String []args){
        Random_Graph g=new Random_Graph(10,20,false,true);
        g.print_Graph();
    }


}
class Node{
    int weight;
    int endpoint;
    public Node(int weight,int endpoint){
        this.weight=weight;
        this.endpoint=endpoint;
    }
}

小白入手,如果有不妥當的地方,還望指教!