2018-04-08 堆排序

堆排序就是选择排序的演化版本。核心思想就是将数据源先整合成一个完全二叉树,这样在第一级节点的数据肯定是最大的,这样数据比较就简单很多了。其中堆排序有个牛逼闪闪的题,叫寻找最小的k个数 就这个链接里老哥说了很多解法,我大概就看了个对排序的解法。题目是假设数组[1,4,5,23,414,523,342,....]是个无序数组,那么,想要找到K个最小数,并且还要给K个最小数排序。
解题核心思想就是先假定这个数组前K个数就已经是我们要的结果,然后把数组前K个数先拿出来,做个完全二叉树的堆,这样就是排好了一个结果集,并且第一个元素肯定是最大的,因为完全二叉树的头结点就是最大值(这种叫最大堆)。然后再把这个头结点和数据源剩下的数进行比较。所以,最难得点其实是将前K个数找出来并且做好一颗完全二叉树(起码这是我觉得难点)。

#include 
using namespace std;

/******************
根据输入的int数组创建一个最大堆
input:      输入的int数组
maxHeap:     最大堆数组
maxHeapCount 最大堆中元素的个数
******************/
void createMaxHeap(const int * input, int * maxHeap, const int maxHeapCount);

/******************
对输入int数组进行操作,使之符合最大堆的条件:
所有结点的值不大于其父结点

maxHeap:     最大堆数组
pos:         最大堆中的元素标志位,由1开始
maxHeapCount 最大堆中元素的个数
******************/
void heapifyMaxHeap(int * maxHeap, const int pos, const int maxHeapCount);

/******************
对最大堆排序,使之由小到大有序

maxHeap:     最大堆数组
maxHeapCount 最大堆中元素的个数
******************/
void maxHeapSort(int * maxHeap, const int maxHeapCount);


/******************
根据指定的长度初始化输入的int数组
bigData:    输入的int数组
arrayLength: 数组长度
******************/
void initBigDataArray(int * bigData, const int arrayLength);

void main()
{
    const int M = 1000;
    const int K = 5;
    int bigDataM[M];
    int maxHeap[K];

    initBigDataArray(bigDataM, M);
   createMaxHeap(bigDataM, maxHeap, K);

    for(int step = K; step < M; ++step)
    {
        if(bigDataM[step] < maxHeap[0])
        {
            maxHeap[0] = bigDataM[step];
            heapifyMaxHeap(maxHeap, 1, K);
        }
    }

    maxHeapSort(maxHeap, K);

    cout<<"bigData array is: ";
    for(int step = 0; step < M; ++step)
    {
        cout< maxHeap[pos - 1])
        largestElemPos = left;
    else
        largestElemPos = pos;

    if(right <= maxHeapCount && maxHeap[right - 1] > maxHeap[largestElemPos - 1])
        largestElemPos = right;

    if(largestElemPos != pos)
    {
        swap(maxHeap[pos - 1], maxHeap[largestElemPos - 1]);
        heapifyMaxHeap(maxHeap, largestElemPos, maxHeapCount);
    }


}

void createMaxHeap(const int * input, int * maxHeap, const int maxHeapCount)
{
   for(int step = 0; step < maxHeapCount; ++step)
    {
        maxHeap[step] = input[step];
    }

    for(int startHeapifyPos = maxHeapCount/2; startHeapifyPos >= 1; --startHeapifyPos)
    {
        heapifyMaxHeap(maxHeap, startHeapifyPos, maxHeapCount);
    }
}

void initBigDataArray(int * bigData, const int arrayLength)
{
    for(int i = 0; i< arrayLength; ++i)
    {
       bigData[i] = rand();
    }
}

void maxHeapSort(int * maxHeap, const int maxHeapCount)
{
    int maxHeapSize = maxHeapCount;
    for(int step = maxHeapSize; step >=2; --step)
    {
        swap(maxHeap[step - 1], maxHeap[0]);
        maxHeapSize -=1;
       heapifyMaxHeap(maxHeap, 1 , maxHeapSize);
    }
}

==============java版=================

public class Solution {
    public ArrayList GetLeastNumbers_Solution(int[] input, int k) {
        ArrayList result = new ArrayList();
        int length = input.length;
        if (k > length || k == 0) {
            return result;
        }
        PriorityQueue maxHeap = new PriorityQueue(k, new Comparator() {

        @Override
        public int compare(Integer o1, Integer o2) {
            return o2.compareTo(o1);
        }
    });
    for (int i = 0; i < length; i++) {
        if (maxHeap.size() != k) {
            maxHeap.offer(input[i]);
        } else if (maxHeap.peek() > input[i]) {
            Integer temp = maxHeap.poll();
            temp = null;
            maxHeap.offer(input[i]);
        }
    }
    for (Integer integer : maxHeap) {
        result.add(integer);
    }
    return result;
  }
}

其中JAVA提供了PriorityQueue这个类就是符合堆特性的队列,其内部是数组结构,所以在构建K个最小堆时候其实直接new一个并且循环放进去就好了。

你可能感兴趣的:(2018-04-08 堆排序)