算法導論--貪心算法--赫夫曼編碼

算法導論上構建赫夫曼編碼的時候,說是用的最小堆,其實是每次都取出來一個最小值,而不是一次性取2個值。這點第一次的時候理解疏忽了。
其實用快排(nlogn)構建一個概率從小到大的結構也行!不過最小堆的操作時間複雜度肯定要小很多(logn)

public class huffuman {
public static void main(String[] args) {
char[] a = new char[]{‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’};
Integer[] b = new Integer[]{45, 13, 12, 16, 9, 5};
HashMap < String, Integer> map = new HashMap< String, Integer >();
map.put(“a”, 45);
map.put(“b”, 13);
map.put(“c”, 12);
map.put(“d”, 16);
map.put(“e”, 9);
map.put(“f”, 5);
ArrayList minHeap = new ArrayList();
minHeap.add(“a”);
minHeap.add(“b”);
minHeap.add(“c”);
minHeap.add(“d”);
minHeap.add(“e”);
minHeap.add(“f”);
int len = minHeap.size();
minHeap(minHeap, len, map);
int addlen = len;
ArrayList nodes= new ArrayList();
for (int i = 0; i < len - 1; i++) {
String first = minHeap.get(0);
Integer firstValue = map.get(first);
minHeap.remove(0);
addlen–;
minHeap(minHeap, addlen,map);
String second = minHeap.get(0);
Integer secondValue = map.get(second);
minHeap.remove(0);
addlen–;
minHeap(minHeap, addlen,map);
Integer count = firstValue + secondValue;
String name = “掙脫枷鎖” + i;
map.put(name, count);
minHeap.add(name);
addHeap(minHeap, map);
addlen++;
minHeap(minHeap, addlen,map);
Node node = new Node(count, name, firstValue, first, secondValue, second);
nodes.add(0,node);
}
nodes.forEach((e) -> {
System.out.println(e);
});
}

private static void minHeap(ArrayList<String> minHeap, int len, HashMap<String, Integer> map) {
    for (int i = ((len / 2) -1); i >= 0; i--) {
        minHeavy(minHeap, i, map);
    }
}

private static void addHeap(ArrayList<String> minHeap, HashMap<String, Integer> map) {
    int len = minHeap.size();
    String name = minHeap.get(len - 1);
    Integer value = map.get(name);
    for (int i = len -1; i > 0; ) {
        int parent = i / 2;
        String parentname = minHeap.get(parent);
        Integer parentvalue = map.get(parentname);
        if(value < parentvalue){
            minHeap.set(parent,name);
            minHeap.set(i,parentname);
            i = i/2;
        }else{
            break;
        }
    }
}

private static void minHeavy(ArrayList<String> minHeap, int i, HashMap<String, Integer> map) {
    int len = minHeap.size();
    String name = minHeap.get(i);
    int value = map.get(name);
    int left = (i + 1) * 2 - 1 ;
    int right = (i + 1) * 2 ;
    int min = i;
    if (right <= len - 1) {
        String rightname = minHeap.get(right);
        int rightvalue = map.get(rightname);
        if (rightvalue < value) {
            minHeap.set(i, rightname);
            minHeap.set(right, name);
            name = rightname;
            min = right;
            value = rightvalue;
        }
    }
    if (left <= len - 1) {
        String leftname = minHeap.get(left);
        int leftvalue = map.get(leftname);
        if (leftvalue < value) {
            minHeap.set(i, leftname);
            minHeap.set(left, name);
            min = left;
        }
    }
    if(i != min){
        minHeavy(minHeap, min, map);
    }
}

static class Node {
    public Integer value = null;
    public String  name  = null;
    public Integer left = null;
    public String leftvalue = null;
    public Integer right = null;
    public String rightvalue = null;

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public Integer getLeft() {
        return left;
    }

    public void setLeft(Integer left) {
        this.left = left;
    }

    public Integer getRight() {
        return right;
    }

    public void setRight(Integer right) {
        this.right = right;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLeftvalue() {
        return leftvalue;
    }

    public void setLeftvalue(String leftvalue) {
        this.leftvalue = leftvalue;
    }

    public String getRightvalue() {
        return rightvalue;
    }

    public void setRightvalue(String rightvalue) {
        this.rightvalue = rightvalue;
    }

    public Node(Integer value, String name, Integer left, String leftvalue, Integer right,   String rightvalue) {
        this.value = value;
        this.name = name;
        this.left = left;
        this.leftvalue = leftvalue;
        this.right = right;
        this.rightvalue = rightvalue;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                ", name='" + name + '\'' +
                ", left=" + left +
                ", leftvalue='" + leftvalue + '\'' +
                ", right=" + right +
                ", rightvalue='" + rightvalue + '\'' +
                '}';
    }
}
 }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章