Prim最小生成树的最小堆的java代码实现

package prim;

public class MinHeapNode {
      
       int v ;
       int weight ;
       public MinHeapNode( int v, int weight) {
             this .v = v;
             this .weight = weight;
      }

}

package prim;

public class MinHeap {
      
       int size ;
       int capacity ;
       int [] pos ;
      MinHeapNode[] array ;
      
       public MinHeap( int v){
             this .size = 0;
             this .capacity = v;
             pos = new int[v];
             array = new MinHeapNode[v];
      }

       public boolean isEmpty(){
             return size ==0;
      }
       //保持堆的性质
       public void holdMinHeap( int idx){
             int left = (idx<<1)+1;
             int right = (idx+1)<<1;
             int min = idx;
             if (left<size && array[left]. weight <array [min]. weight){
                  min = left;
            }
             if (right<size && array[right]. weight <array [min]. weight){
                  min = right;
            }
             if (min!=idx){
                   pos [array [min]. v] = idx;
                   pos [array [idx]. v] = min;
                  MinHeapNode temp;
                  temp = array [min];
                   array [min] = array [idx];
                   array [idx] = temp;
                  holdMinHeap(min);
            }
      }
       //建立最小堆
       public void createMinHeap(){
             int idx = ( this. size-1)/2;
             while (idx>=0){
                  holdMinHeap(idx);
                  idx--;
            }
      }
       //取得最小值
       public MinHeapNode getMinNode(){
            MinHeapNode min = this .array [0];
             this .array [0] = array[ size-1];
             pos [min.v ] = size-1;
             pos [array [0]. v] = 0;
             size --;
            holdMinHeap(0);
             return min;
      }
       //判断某个节点是否在堆中
       public boolean isInHeap( int v){
             if (pos [v]< size){
                   return true;
            }
             return false;
      }
       //pos 避免了每次都要遍历整个堆
       public void deleteKey( int v, int key){
             int i = pos [v];
             array [i].weight = key;
             while (i>0&&array [i]. weight< array [(i-1)/2].weight ){
                   pos [array [i]. v] = (i-1)/2;
                   pos [array [(i-1)/2]. v] = i;
                  MinHeapNode temp = array [i];
                   array [i] = array [(i-1)/2];
                   array [(i-1)/2] = temp;
                  i = (i-1)/2;
            }
      }
}


package prim;

public class EdgeNode {

       int v ;
       int weight ;
      EdgeNode next ;
       public EdgeNode( int v, int weight, EdgeNode next) {
             this .v = v;
             this .weight = weight;
             this .next = next;
      }
}

package prim;


public class GraphEdge {

       /**
       *
       */
      EdgeNode next ;

       public GraphEdge(EdgeNode next) {
             this .next = next;
      }
}

package prim;



public class Graph {
      
       int v ;
      GraphEdge[] edges ;
      
       public Graph( int v){
             this .v = v;
             edges = new GraphEdge[v];
             for (int i=0;i<v;i++){
                   edges [i] = new GraphEdge( null);
            }
      }
      
       //添加边
    public void addEdge( int src,EdgeNode e){
       e. next = this. edges [src].next ;
       this. edges [src].next = e;
       EdgeNode node = new EdgeNode(src, e.weight , null);
       node. next = this .edges [e. v]. next;
       this. edges [e.v ].next = node;
    }
   
    public void getPrimTree(){
       int[] parent = new int [v ];
      MinHeap heap = new MinHeap(v );//初始化最小堆
       for( int i=1;i<v ;i++){
            heap. array [i] = new MinHeapNode(i, Integer. MAX_VALUE);
      }
      heap. array [0] = new MinHeapNode(0, 0);
       for( int i=0;i<v ;i++){
            heap. pos [i] = i;
      }
      parent[0] = -1;
      heap. size = v ;
      heap.createMinHeap(); //创建最小堆
       while(!heap.isEmpty()){
            MinHeapNode node = heap.getMinNode(); //取得最小的weight的节点
             //heap.holdMinHeap(0);
             int u = node.v ;
            EdgeNode n = this .edges [u]. next; //查看其相邻的节点
             while (n!=null ){
                   if (heap.isInHeap(n.v )&&n. weight<heap. array [heap.pos [n. v]]. weight){
                         //heap.array[heap.pos[n.v]].weight = node.weight;
                        parent[n. v] = u;
                        heap.deleteKey(n. v, n. weight );//改变节点的值
                  }
                  n = n. next ;
            }
      }
       for( int i=1;i<v ;i++){
            System. out .println(i+"->" +parent[i]);
      }
    }
}

package prim;

public class PrimAdjacency {

       /**
       * @param args
       */
       public static void main(String[] args) {
            
            Graph g = new Graph(7);
            g.addEdge(0, new EdgeNode(3, 1, null ));
            g.addEdge(5, new EdgeNode(6, 1, null ));
            g.addEdge(0, new EdgeNode(1, 2, null ));
            g.addEdge(2, new EdgeNode(3, 2, null ));
            g.addEdge(1, new EdgeNode(3, 3, null ));
            g.addEdge(0, new EdgeNode(2, 4, null ));
            g.addEdge(3, new EdgeNode(6, 4, null ));
            g.addEdge(2, new EdgeNode(5, 5, null ));
            g.addEdge(4, new EdgeNode(6, 6, null ));
        g.getPrimTree();
      }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值