zoukankan      html  css  js  c++  java
  • 考研数据结构笔记—堆排序

    完全二叉树是效率很高的数据结构,堆是一种完全二叉树或者近似完全二叉树,所以效率同样极高。目前十分常用的排序算法、Dijkstra算法、Prim算法等都要用堆才能优化。

    堆排序是一种选择排序算法,与原序列的初始排列次序无关,即最好、最坏和一般情况排序的时间复杂度不变,均为O(nlgn)。而且,堆排序只需要一个记录元素大小的辅助空间(供交换使用),故空间复杂度为O(1)。正由于堆排序不仅时间复杂度小,而且空间复杂度O(1)也是最小,所以是用于排序的最佳选择。

    堆的定义 

    n个元素序列 { k0,k1,..., k} 当且仅当满足下列条件之一时,称之为堆(其中 i = 0, 1, ..., n/2 向下取整)。

    • ki <= k2i+1 且 k<= k2i+2(最小堆)
    • ki >= k2i+1 且 ki >= k2i+2(最大堆)

    堆排序实现  

    利用最大堆性质实现堆排序

    #include <iostream>
    using namespace std;
    
    /*交换数组中两个元素的值*/
    void Swap(int *arr, int a, int b)
    {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
    
    /*(大根)堆调整*/
    void maxHeapify(int *arr, int length, int curNode)
    {
        /*找出当前节点和其左右节点三者的最大值*/
        int maxNode = curNode;
        int left = curNode * 2 + 1;
        int right = curNode * 2 + 2;
        if (left < length && arr[left] > arr[maxNode]) //左孩子存在且较大
            maxNode = left;
        if (right < length && arr[right] > arr[maxNode]) //右孩子存在且较大
            maxNode = right;
    
        if (maxNode != curNode)    //当前节点不是最大则需要交换
        {
            Swap(arr, maxNode, curNode);
            maxHeapify(arr, length, maxNode);  //子节点需重新调整
        }
    }
    
    /*(最大)堆排序
    *思想:
    *1、构建最大堆
    *2、从最后一个元素开始只第二个元素将依次与首元素交换
    *3、进行数组中当前元素前面的所有元素的局部调整堆
    *上面步骤2和步骤3将所有元素都与首元素交换,将局部范围内的最大值沉到后面,然后进行当前元素前面所有元素的局部范围内的堆调整
    *即在数组A中,当前元素索引为i,将A[i]与A[0]交换,将A[0,1,...,i]中最大的值放到A[i],然后进行A[0,1,...,i-1]堆调整,
    *将A[0,1,...,i-1]内的最大值放到A[0]中,待下一次交换使用,实现将局部的最大值依次沉到数组后面,完成排序
    */
    void heapSort(int *arr, int length)
    {
         //构建堆
        for (int i = length / 2 - 1; i >= 0; i--)  //从最后一个非叶节点开始
        {
            maxHeapify(arr, length, i);
        }
    
        for (int i = length - 1; i > 0; i--)
        {
            Swap(arr, 0, i);  //与首元素交换
            maxHeapify(arr, i, 0);  //调整堆
        }
    }
    
    int main()
    {
        cout << "堆排序算法实现" << endl;
        int data[] = { 6,8,2,3,9,7,4,1,5,10 };
        cout << "排序之前的数据:";
        for (int i = 0; i<10; i++)
            cout << data[i] << " ";
        cout << endl;
        heapSort(data, 10);
        cout << "排序之后的数据:";
        for (int i = 0; i<10; i++)
            cout << data[i] << " ";
        cout << endl;
        system("pause");
        return 0;
    }

    堆排序优化实现,重新理解

    #ifndef _HEAP_SORT_H
    #define _HEAD_SORT_H
    
    class heapsort {
    
    public:
        void sort(int *a, int len) {
            if (len <= 1){
                return;
            }
    
            //建堆,保证头结点为数组最大值
            createHeap(a, len);
    
            /*
            * 从数组最后一位开始,依次递减, a[i]和头结点交换,即a[i]等于a[0~i]中最大值
            * 前i-1个元素再堆化
            * 这样数组每一个位置i都能得到a[0~i]中的最大值
            * 最后使得整个数组有序
            */
            for (int i=len-1; i>0; --i) {
                swap(a[0], a[i]);
                heapify(a, i-1, 0);
            }
        }
    
    private:
        void createHeap(int *a, int len) {
            for (int i = len/2 - 1; i>=0; --i) {
                heapify(a, len-1, i);
            }
        }
    
        void heapify(int *a, int n, int i) {
            while (true) {
                int maxPos = i;
                int left  = i * 2 + 1;
                int right = i * 2 + 2;
                if (left <= n && a[left] > a[maxPos]) {
                    maxPos = left;
                }
                if (right <= n && a[right] > a[maxPos]) {
                    maxPos = right;
                }
                if (maxPos == i) {
                    break;
                }
                swap(a[i], a[maxPos]);
                i = maxPos;
            }
        }
        
        void swap(int& a, int& b) {
            int tmp = a;
            a = b;
            b = tmp;
        }
    };
    
    #endif
  • 相关阅读:
    读《见识》 | 当别人扇了你一巴掌
    Java集合类
    Java数据结构简述
    Java加密算法
    Java JDK与JRE
    Java String、StringBuilder、StringBuffer[笔记]
    Java同步(Synchronization)
    Java断言(Assertion)
    Java strictfp
    Java Native Interface(JNI)
  • 原文地址:https://www.cnblogs.com/evenleee/p/8529169.html
Copyright © 2011-2022 走看看