堆排序

如果堆的大小是提前知道的,那么可以将堆存储在一个ArrayList或一个数组里。如下图使用数组存储堆,对于位置i处的结点,它的左孩子在位置2i+1处,它的右孩子在位置2i+2处,而它的父亲在位置(i - 1)/2处。

如下是一些堆具有的常见操作:

添加一个新结点:

为了给堆添加一个新结点,首先将它添加到堆的末尾,然后和它的父节点比较,如果大,就上移,直到不必父节点大。

删除根节点:

经常需要从堆中删除最大的元素,也就是这个堆中的根节点。删除根节点之后就必须重建这个树以保持堆的特性,重建过程如下:

  将最后一个节点放到根节点当做当前节点;

  然后和左右子节点比较,如果当前节点是这三个节点中最大的,那么这棵树建立成功;如果不是,需要和两个子节点中最大的节点交换位置,然后以当前位置作为当前节点,继续和子节点比较,直到当前节点是最大的,或者当前节点已经成为叶子节点。

 

 

Heap.java代码如下:

package test;

public class Heap<E extends Comparable> {

    private java.util.ArrayList<E> list = new java.util.ArrayList<E>();

    public Heap(){}

    public Heap(E[] objects){
        for(int i = 0; i < objects.length; i++)
        add(objects[i]);
    }

    public void add(E newObject){
        list.add(newObject);
        int currentIndex = list.size() - 1;

        while(currentIndex > 0){
            int parentIndex = (currentIndex - 1)/2;
            if(list.get(currentIndex).compareTo(list.get(parentIndex)) > 0){
                E temp = list.get(currentIndex);
                list.set(currentIndex, list.get(parentIndex));
                list.set(parentIndex, temp);
            }
            else
                break;
            currentIndex = parentIndex;
        }
    }

    public E remove(){
        if(list.size() == 0) return null;

        E removedObject = list.get(0);
        list.set(0, list.get(list.size() - 1));
        list.remove(list.size() - 1);

        int currentIndex = 0;
        while(currentIndex < list.size()){
            int leftChildIndex = 2 * currentIndex + 1;
            int rightChildIndex = 2 * currentIndex + 2;

            if(leftChildIndex >= list.size()) //这说明当前节点已经是叶子了,这时树已经是堆
                break;
            int maxIndex = leftChildIndex;
            if(rightChildIndex < list.size()){ //这一段是为了找到左右子节点中最大的节点
                if(list.get(rightChildIndex).compareTo(list.get(maxIndex))> 0){
                    maxIndex = rightChildIndex;
                }
            }

            if(list.get(currentIndex).compareTo(list.get(maxIndex)) < 0){
                E temp = list.get(currentIndex);
                list.set(currentIndex, list.get(maxIndex));
                list.set(maxIndex, temp);
                currentIndex = maxIndex;
            }
            else
                break; //这时树已经是堆
        }
        return removedObject;
    }
}

 

HeapSort.java代码如下:

package test;

public class HeapSort {
    public static <E extends Comparable> void heapSort(E[] list){
        Heap <E> heap = new Heap<E>();

        for(int i = 0; i < list.length; i++)
            heap.add(list[i]);
            for(int i = list.length - 1; i >= 0; i--)
                list[i] = heap.remove();
    }
    public static void main(String []args){
        Integer [] list = {1,2,3,4,5,6};
    // int [] list = {5, 2, 9, 3, 8, 4, 5, 5, 0, 1, 6, 7};
        for(int i = 0; i < list.length; i++)
        System.out.print(list[i] + " ");
        System.out.print("\n");

        heapSort(list);

        for(int i = 0; i < list.length; i++)
        System.out.print(list[i] + " ");
    }
}

 

 

 

 

 

 

 

 

posted @ 2014-03-12 11:58  hansonzhe  阅读(212)  评论(0编辑  收藏  举报