码迷,mamicode.com
首页 > 编程语言 > 详细

堆排序实践

时间:2015-03-31 00:36:19      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

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

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("\n");
    printf("开始排序\n");

    int tick = GetTickCount();

    HeapSort(a, MAX_LEN );

    printf("\n");
    printf("排序用时:%d\n", GetTickCount() - tick);

    for (int i = 0; i < MAX_LEN; i++)
    {
        printf("%d ", a[i]);
    }

    system("pause");

    return 0;
}

 

堆排序实践

标签:

原文地址:http://www.cnblogs.com/davygeek/p/4379596.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!