景兄弟手撕算法之堆排序

堆,其實也是完全二叉樹的一種,每一個根節點都大於它的節點叫大頂堆,每一個根節點都小於它的節點叫小頂堆。

下面是基於大頂堆的堆排序實現:

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 +
                '}';
    }
}

 

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