排序之堆排序

在本例中实现了堆数据结构,sort()方法排序堆实例。

import java.util.Comparator;
import java.util.Iterator;
import java.util.function.Consumer;

/**
 * 二叉堆
 * 成员变量:数组 arr、元素数量 count、
 * 成员方法:是否空 isEmpty 、大小 size、插入 insert、删除最大值并返回 deleteMax、
 *             比较less、交换exch、下沉sink、上浮swim
 */
public class Heap <Key extends Comparable<Key>> implements Iterable<Key>{
    private Key[] arr; //堆内部维护的数组
    private int count; //数组内部的元素

    public Heap(Key[] array){
        count = array.length;
        arr = (Key[])new Comparable[count+1];
        for(int i=1;i<=array.length;i++){
            arr[i] = array[i-1];
        }
    }

    public void resize(int size){
        Key[] temp = (Key[])new Comparator[size];
        for(int i=1;i<=count;i++){
            temp[i]=arr[i];
        }
        arr = temp;
    }

    public boolean isEmpty() {
        if(count==0)return true;
        return false;
    }
    public int size(){
        return count;
    }

    public void insert(Key key){
        if(count+1>=arr.length){
            resize(count*2);
        }
        arr[count+1] = key;
        count++;
        swim(count);
    }

    public Key deleteMax(){
        if(isEmpty()) return null;
        Key temp = arr[1];
        exch(1,count);
        arr[count--]=null;
        sink(1,count);
        return temp;
    }
    public boolean less(int a,int b){
        if(arr[a].compareTo(arr[b])<0) return true;
        return false;
    }

    public void exch(int a,int b){
        Key temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
    // sink() swim() 方法是堆数组的关键
    public void sink(int k, int n){
        while (2*k<=n){//有子节点
            int j=2*k;
            if(j+1<=n && less(j,j+1)) j++;
            if(less(j,k)) break;
            exch(j,k);
            k=j;
        }
    }

    public void swim(int k){
        int j=k/2;
        while (j>=1){//有父节点
            if(less(j,k)){
                exch(j,k);
                k=j;
            }
        }
    }

    public void sort(){
        //初始化数组
        //从倒数的二排开始使用sink()方法逐渐是整个堆有序化
        for(int i = count/2; i>=1; i--){
            sink(i,count);
        }
        System.out.println("初始化结束");
        //排序
        int N = count;
        while(N>1){
            exch(1,N--);
            sink(1,N);  //注意! 此处sink()方法的第二个参数为N; 因为需要sink()方法排序堆的大小为N
        }
        System.out.println("排序结束");
    }

    //迭代器
    @Override
    public Iterator<Key> iterator() {
        return new Iterator<Key>() {
            int i = 1;
            @Override
            public boolean hasNext() {
                if(i<=count)return true;
                return false;
            }

            @Override
            public Key next() {
                return arr[i++];
            }
        };
    }
}

 

 

/**
 * 测试案例
 */
public class TestCase {
    public static void main(String[] args) {
        Integer[] a = new Integer[]{1,6,34,2,5,3,4,45,6,22};
        Heap<Integer> integerHeap = new Heap<>(a);
        System.out.println("start sort");
        integerHeap.sort();
        System.out.println("sorted");
        for(Integer e : integerHeap){
            System.out.println(e);
        }
    }
}

//结果
start sort
初始化结束
排序结束
sorted
1
2
3
4
5
6
6
22
34
45

 

 

只使用堆排序,静态方法

public class HeapSort{

    public static void sink(Comparable[] arr, int k, int n){  //使用了多态,要求数组实现Comparable接口
        while (2*k<=n){//有子节点
            int j=2*k;
            if(j+1<=n && less(arr,j,j+1)) j++;
            if(less(arr,j,k)) break;
            exch(arr,j,k);
            k=j;
        }
    }

    public static boolean less(Comparable[] arr,int a,int b){
        if(arr[a].compareTo(arr[b])<0) return true;
        return false;
    }

    public static void exch(Comparable[] arr, int a,int b){
        Comparable temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

    public static void sort(Comparable[] arr){
        for(int i=arr.length/2;i>=1;i--){
            sink(arr, i, arr.length-1);
        }
        int n=arr.length-1;
        while(n>1){
            exch(arr,1,n);
            sink(arr,1,--n);
        }
    }
}

 

import java.util.Arrays;

/**
 * 测试案例
 */
public class TestCase {
    public static void main(String[] args) {
        Integer[] arr = new Integer[]{0,1,6,34,2,5,3,4,45,6,22};//数组索引为0的位置不放元素
        HeapSort.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

//结果
[0, 1, 2, 3, 4, 5, 6, 6, 22, 34, 45]

 

上一篇:Flume基础知识


下一篇:java8 Stream之原理