• 堆排序实践


    今天自己研究了堆排序,发现个问题,你认证他就很简单你不认真就很难。用心去看任何算法都是很有魅力的,以前复习的时候感觉所有的算法都是背会的,这次复习感觉很爽所有的都是靠理解来处理;下面我就把自己简单的理解写写做个小记录方便后续巩固

    1.先把数据构建一个堆,这里我们选用大根堆(就是每个节点的值都不大于其父节点的值)。

      处理的具体步骤是从树的第一个非叶子节点开始,一般都是从n/2节点开始,如果2*n<=n 则2*n是其左子节点, 如果2*n+1 <=n。

      从n/2节点开始,把n/2节点和其左右子节点中较大的值进行比较,如果子节点的值大于父节点的值那么就交换两者的值。

      处理完该节点在下一个非叶子节点重复上面的步骤,如果出现数据交换的情况导致堆被破坏就重新整理调整。直至所有的节点都满足为止。

    2.经过上面的处理之后,下面就开始排序,主要就是把堆最后一个子节点n-1的数据和根节点0的数据对换,对换后我们就得到了新的被破坏的堆和排序数组   n,继续按   照步骤1的过程重新调整被破坏的堆,调整完成后把最新的堆的最后一个数据n-2的数据和根节点0的数据对换,...一直重复知道得到我们的排序数组[a0 a1 a2 ... n]为  止。

    下面贴个我写的代码

    void HeapSort(int* a, int n)
    {
        for (int i = n / 2 - 1; i >= 0; i--)//从树的第一个非叶子节点的节点开始,第一个非叶子节点的节点id是n/2
        {
            while (2 * i + 1 < n)//有左节点
            {
                int j = 2 * i + 1;
                if ((j + 1 < n) && (a[j] < a[j + 1]))//有右侧节点,同时右侧节点大于左侧节点
                {
                    ++j;
                }
    
                if (a[i] < a[j])//交换父节点和子节点的数据
                {
                    int t = a[i];
                    a[i] = a[j];
                    a[j] = t;
                    i = j;//堆被破坏,重新整理
    
                }
                else
                {
                    break;
                }
            }
        }
    
        //调整完后进行处理
        for (int i = n - 1; i > 0; i--)
        {
            int t = a[i];
            a[i] = a[0];
            a[0] = t;
    
            //交换完毕,开始重新调整
            int k = 0;
            while (2 * k + 1 < i)
            {
                int j = 2 * k + 1;
                if ((j + 1) < i && a[j] < a[j + 1])
                {
                    ++j;
                }
    
                if (a[k] < a[j])
                {
                    int t = a[k];
                    a[k] = a[j];
                    a[j] = t;
                    k = j;
                }
                else
                {
                    break;
                }
            }
        }
    }
    
    #define  MAX_LEN 10
    int _tmain(int argc, _TCHAR* argv[])
    {
        int *a = new int[MAX_LEN];
        memset(a, 0, MAX_LEN);
        srand(time_t(NULL));
    
        for (int i = 0; i < MAX_LEN; i++)
        {
            a[i] = rand() % 100;
            printf("%d ", a[i]);
        }
        printf("
    ");
        printf("开始排序
    ");
    
        int tick = GetTickCount();
    
        HeapSort(a, MAX_LEN );
    
        printf("
    ");
        printf("排序用时:%d
    ", GetTickCount() - tick);
    
        for (int i = 0; i < MAX_LEN; i++)
        {
            printf("%d ", a[i]);
        }
    
        system("pause");
    
        return 0;
    }
  • 相关阅读:
    GB/T 29311-2020 电气绝缘材料和系统 交流电压耐久性评定
    GB/T 36290.1-2020 电站流程图 第1部分:制图规范
    GB 50646-2020 特种气体系统工程技术标准
    T/CECS 644-2019 恒温恒湿实验室工程技术规程
    GB/T 38808-2020 建筑结构用波纹腹板型钢
    DL/T 1848-2018 220kV和110kV变压器中性点过电压保护技术规范
    这一周发生的事,也该醒醒了!
    pytest-09(conftest.py的层级作用)
    pytest-08(fixtrue的详细使用)
    pytest-07(使用装饰器fixtrue中的autose=True)
  • 原文地址:https://www.cnblogs.com/davygeek/p/4379596.html
Copyright © 2020-2023  润新知