美文网首页
2018-04-08 堆排序

2018-04-08 堆排序

作者: laohan_王 | 来源:发表于2018-04-08 14:51 被阅读0次

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

    #include <iostream>
    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<<bigDataM[step]<<" ";
        }
        cout<<endl;
    
        cout<<"Output maxHeap from less to larger: ";
        for(int step = 0; step < K; ++step)
        {
            cout<<maxHeap[step]<<" ";
        }
        cout<<endl;
    
        cout<<"Output maxHeap from larger to less: ";
        for(int step = 0; step < K; ++step)
        {
            cout<<maxHeap[K - 1 - step]<<" ";
        }
        cout<<endl;
    
        return;
    }
    
    void heapifyMaxHeap(int * maxHeap, const int pos, const int maxHeapCount)
    {
        int left = 2 * pos;
        int right = 2 * pos + 1;
        int largestElemPos = 0;
       if(left <= maxHeapCount && maxHeap[left - 1] > 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<Integer> GetLeastNumbers_Solution(int[] input, int k) {
            ArrayList<Integer> result = new ArrayList<Integer>();
            int length = input.length;
            if (k > length || k == 0) {
                return result;
            }
            PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
    
            @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 堆排序

          本文链接:https://www.haomeiwen.com/subject/bbophftx.html