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();
}
}
Prim最小生成树的最小堆的java代码实现
最新推荐文章于 2020-07-01 16:30:56 发布