zoukankan      html  css  js  c++  java
  • 堆排序实践

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

    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;
    }
  • 相关阅读:
    IE 8无法使用R12的解决办法
    ERP系统里的BOM展开函数
    BOM递归查询小实例
    使用标准Package提交Workflow
    查询WIP离散工单的所有组件
    Oracle EBS 各模块中文名称及英文缩写
    ORACLE EBS CUX用户的创建(转)
    HR人员基本信息、分配信息和地址信息SQL
    在Oracle中计算Onhand Quantity
    来自于Mozilla Networks演示工作室的超酷CSS3/Javascript动画演示
  • 原文地址:https://www.cnblogs.com/davygeek/p/4379596.html
Copyright © 2011-2022 走看看