• 堆排序


    这里介绍了堆的操作 https://www.cnblogs.com/zuofaqi/p/9665619.html

    堆还可以用来做堆排序,其过程是:对于从小到大的排序,使用最大堆。建堆之后,交换第一个元素和最后一个堆元素,这样,最后一个堆元素A[n-1]就是最大值,而A[0...n-2]的堆结构就被破坏了,通过堆顶元素的下沉操作,使A[0...n-2]再次成为一个堆。再交换第一个元素和最后一个堆元素,循环下去,最后,整个堆都是有序的。

    void heapSort(int* arr, int heapsize)
    {
        // 建堆
        adjust_by_sink(arr, heapsize);
        
        while (heapsize > 1)
        {
            int tmp = arr[0];
            arr[0] = arr[heapsize-1];
            arr[heapsize-1] = tmp;
            // 堆长减1, 新堆首元素下沉
            heapsize--;
            sink(arr, 0, heapsize);
        }
    }

    通过这个过程,我们可以知道,堆排序是原址排序。同时,堆排序是不稳定排序,比如 [2,6,8,5,0,1,7,7]这个数组,在使用下沉法建堆的时候,两个7的相对位置就变了。堆排序时间复杂度是O(nlogn)

    完整代码:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define ARRLEN 100
    
    #define LEFT(idx) (((idx)<<1)+1)
    #define RIGHT(idx) (((idx)<<1)+2)
    #define PARENT(idx) (((idx)-1)>>1)
    
    
    // 下沉
    void sink(int* arr, int index, int heapsize)
    {
        // 左子树节点超出堆长度范围
        if (LEFT(index) > heapsize-1)
        {
            return;
        }
    
        int maxidx = -1;
        // 右子树节点超出堆长度范围,或者左节点的值比右节点的值大
        if (RIGHT(index) > heapsize-1 || (arr[LEFT(index)] > arr[RIGHT(index)]))
        {
            maxidx = LEFT(index);
        }
        else
        {
            maxidx = RIGHT(index);
        }
    
        if (maxidx != -1 && arr[maxidx] > arr[index])
        {
            int tmp = arr[maxidx];
            arr[maxidx] = arr[index];
            arr[index] = tmp;
            sink(arr, maxidx, heapsize);
        }
    }
    
    // 上浮
    void upward(int* arr, int index, int heapsize)
    {
        if (0 == index)
        {
            return;
        }
    
        if (arr[PARENT(index)] < arr[index])
        {
            int tmp = arr[index];
            arr[index] = arr[PARENT(index)];
            arr[PARENT(index)] = tmp;
            upward(arr, PARENT(index), heapsize);
        }
    }
    
    void adjust_by_sink(int* arr, int heapsize)
    {
        // 下沉法,从最后一个非叶子节点开始,到根节点,依次执行下沉
        for (int i = PARENT(heapsize-1); i >= 0; i--)
        {
            sink(arr, i, heapsize);
        }
    }
    
    void adjust_by_upward(int* arr, int heapsize)
    {
        // 上浮法,从根节点到最后一个节点,依次执行上浮
        for (int i = 0; i < heapsize; i++)
        {
            upward(arr, i, heapsize);
        }
    }
    
    int insert(int* arr, int value, int& heapsize)
    {
        if (heapsize > ARRLEN)
        {
            return -1;
        }
    
        arr[heapsize] = value;
        upward(arr, heapsize, heapsize+1);
        heapsize++;
    
        return 0;
    }
    
    void del(int* arr, int& heapsize)
    {
        if (heapsize <= 0)
        {
            return;
        }
    
        arr[0] = arr[heapsize-1];
        heapsize--;
        sink(arr, 0, heapsize);
    }
    
    void heapSort(int* arr, int heapsize)
    {
        // 建堆
        adjust_by_sink(arr, heapsize);
        
        while (heapsize > 1)
        {
            int tmp = arr[0];
            arr[0] = arr[heapsize-1];
            arr[heapsize-1] = tmp;
            // 堆长减1, 新堆首元素下沉
            heapsize--;
            sink(arr, 0, heapsize);
        }
    }
    
    int main()
    {
        int arr[ARRLEN] = {2,3,4,5,1,2,3,7};
        int heapsize = 8;
    
        heapSort(arr, heapsize);
    
        for (int i = 0; i < heapsize; i++)
        {
            printf("%d
    ", arr[i]);
        }
    
        return 0;
    }
  • 相关阅读:
    [转] 计算机网络中的服务原语
    VMWare的三种网络连接方式
    Vim常用操作
    [转] 图解单片机下载程序电路原理之USB转串口线、CH340、PL2303、MAX232芯片的使用
    [转] MMU 配置
    [转] C++项目中的extern "C" {}
    数据结构62:表插入排序算法
    数据结构61:2-路插入排序算法
    数据结构60:折半插入排序算法(折半排序算法)
    数据结构59:插入排序算法
  • 原文地址:https://www.cnblogs.com/zuofaqi/p/9671465.html
Copyright © 2020-2023  润新知