景兄弟手撕算法之堆排序

堆,其实也是完全二叉树的一种,每一个根节点都大于它的节点叫大顶堆,每一个根节点都小于它的节点叫小顶堆。

下面是基于大顶堆的堆排序实现:

import java.util.Arrays;

/**
 * 实现堆结构和操作
 */

public class Heap {
    //创建堆,创建一个存储对中的元素数组
    private int[] data;
    //堆中存储数据量最大个数
    private int size;
    //堆中以及存储元素的个数
    private int count;
    public Heap(int cp){
        this.data = new int[cp+1];
        this.size = cp;
        this.count = 0;
    }

    public static void main(String[] args) {
        Heap heap = new Heap(7);
        int[] array = new int[7];
        array[1] = 2;
        array[2] = 6;
        array[3] = 9;
        array[4] = 0;
        array[5] = 3;
        array[6] = 5;
        System.out.println(Arrays.toString(array));
        heap.headSort(array);
        System.out.println(Arrays.toString(array));
    }

    private void sort(int[] array,int n){
        while (n>1){
            swp(array,1,n);
            headT2B(array,1,--n);
        }
    }
    private void buildHeap(int[] data,int n){
        for(int i=n/2;i>0;i--){
            heapT2B(data,i,n);
        }
    }

    private void heapT2B(int[] data,int begin,int end){
        while (true){
            //定义最大值的下标
            int maxPos = begin;
            //比较当前节点和左右子节点关系,求出最大值
            if(2*begin <= end && data[maxPos]<data[2*begin]){
                maxPos = 2*begin;
            }
            if(2*begin+1<=end && data[maxPos]<data[2*begin+1]){
                maxPos = 2*begin+1;
            }
            if(begin == maxPos){
                break;
            }
            swp(data, begin, maxPos);

            begin = maxPos;
        }
    }

    public void headSort(int[] array){
        //1.建堆
        buildHeap(array,array.length-1);
        //排序
        sort(array,array.length-1);
    }

    /**
     * 从堆顶删除元素
     */
    public int remove(){
        int max = data[1];
        data[1] = data[count--];
        this.headT2B(data,1,count);
        return max;
    }

    /**
     * 自顶向下堆化
     * @param data
     */
    private void headT2B(int[] data,int begin,int end){
        while (true){
            //定义最大值的下标
            int maxPos = begin;
            //用当前节点和他的左右子节点比较,找出最大值
            if(2*begin<end && data[maxPos]<data[2*begin]){
                maxPos = 2*begin;
            }

            if(2*begin+1<=end && data[maxPos]<data[2*begin+1]){
                maxPos = 2*begin+1;
            }
            if(begin==maxPos){
                break;
            }
            swp(data,begin,maxPos);
            begin = maxPos;
        }
    }

    public void insert(int data){
        if(count>=size){
            //堆已经满了
            return;
        }
        this.data[++count] = data;
        //堆化操作
        this.heapB2T(this.data,count);
    }

    /**
     * 向队中插入元素【堆化--》数据交换】
     * 自底向上的堆化操作
     * @return
     */
    private void heapB2T(int[] data ,int end){
        int i = end;
        //根节点小于子节点的时候需要堆数据元素进行交换
        while (i/2>0 &&data[i/2]<data[i]){
            swp(data,i/2,i);
            i = i/2;
        }
    }

    private void swp(int[] array,int i,int j){
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }


    @Override
    public String toString() {
        return "Heap{" +
                "data=" + Arrays.toString(data) +
                ", size=" + size +
                ", count=" + count +
                '}';
    }
}

 

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