堆排序实践

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

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;
}
时间: 2024-12-12 13:38:19

堆排序实践的相关文章

SuperHakce 春招备战算法实践之堆排序

HeapSort 堆排序 堆排序是一种树形选择排序方法,它的特点是:在排序的过程中,将array[0,...,n-1]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲节点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(最小)的元素. 1. 若array[0,...,n-1]表示一颗完全二叉树的顺序存储模式,则双亲节点指针和孩子结点指针之间的内在关系如下: 任意一节点指针 i:父节点:i==0 ? null : (i-1)/2  左孩子:2*i + 1  右孩子:2*i + 2 2

Heapsort 堆排序算法详解(Java实现)

Heapsort (堆排序)是最经典的排序算法之一,在google或者百度中搜一下可以搜到很多非常详细的解析.同样好的排序算法还有quicksort(快速排序)和merge sort(归并排序),选择对这个算法进行分析主要是因为它用到了一个非常有意思的算法技巧:数据结构 - 堆.而且堆排其实是一个看起来复杂其实并不复杂的排序算法,个人认为heapsort在机器学习中也有重要作用.这里重新详解下关于Heapsort的方方面面,也是为了自己巩固一下这方面知识,有可能和其他的文章有不同的入手点,如有错

数据结构精要------直接选择和堆排序算法

上篇总结中主要实践了算法的内排序的交换排序,那么接下来我们继续实践选择排序的两种:直接选择和堆排序算法. -----直接选择排序 package com.sort; /** * 直接选择排序算法 * @author weixing-yang * * 算法思路: * 首先找出最大元素,将其与a[n-1]位置置换. * 然后在余下的n-1个元素中寻找最大元素,将其与a[n-2]位置置换. * 如此进行下去,知道n个元素排序完成. */ public class SelectSort { public

一步一步写算法(之堆排序)

原文:一步一步写算法(之堆排序) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 堆排序是另外一种常用的递归排序.因为堆排序有着优秀的排序性能,所以在软件设计中也经常使用.堆排序有着属于自己的特殊性质,和二叉平衡树基本是一致的.打一个比方说,处于大堆中的每一个数据都必须满足这样一个特性: (1)每一个array[n] 不小于array[2*n] (2)每一个array[n]不小于array[2 * n + 1] 构建这样一个堆只是基础,后

数据结构实践——大数据集上排序算法性能的体验

本文是针对[数据结构基础系列(9):排序]的实践项目. [项目 - 大数据集上排序算法性能的体验] 设计一个函数,产生一个至少5万条记录的数据集合.在同一数据集上,用直接插入排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序等算法进行排序,记录所需要的时间,经过对比,得到对复杂度不同的各种算法在运行时间方面的感性认识. 提示1:这一项目需要整合多种排序算法,可以考虑先建设排序算法库,作为我们这门课算法库的收官之作: 提示2:本项目旨在获得对于复杂度不同算法的感性认识,由于数据分布

排序算法&lt;No.5&gt;【堆排序】

算法,是系统软件开发,甚至是搞软件的技术人士的核心竞争力,这一点,我坚信不疑.践行算法实践,已经有一段时间没有practise了,今天来一个相对麻烦点的,堆排序. 1. 什么是堆(Heap) 这里说的堆,是一种数据结构,不是指计算机系统中的存储类型.堆是一种完全二叉树.说到完全二叉树,估计很多人都会想问,什么是完全二叉树,那满二叉树呢?先看看定义完全二叉树和满二叉树: 满二叉树是指这样的一种二叉树:除最后一层外,每一层上的所有结点都有两个子结点.在满二叉树中,每一层上的结点数都达到最大值,即在满

【实习记】2014-08-27堆排序理解总结+使用typedef指代函数指针

过程记录 4个月前C语言版的七大排序算法实践让我在写C++版时轻车熟路.特别是冒泡,插入,希尔,选择这四种排序不用调试即运行成功.输出的效果与C语言做的版本完全一样,其中令我印象深刻的是,cout对浮点的处理远不如printf简单明了.非常让开发者难受. 写C++版时有所改进. #define sortfunc _selsort 可以用 typedef void (*sort_t)(vector<int>& arr); sort_t sortfunc = _selsort; 两句代替.

腾讯大规模Hadoop集群实践

腾讯大规模Hadoop集群实践 转自:http://www.csdn.net/article/2014-02-19/2818473-Tencent-Hadoop ID lishilong404740787 TDW是腾讯最大的离线数据处理平台.本文主要从需求.挑战.方案和未来计划等方面,介绍了TDW在建设单个大规模集群中采取的JobTracker分散化和NameNode高可用两个优化方案. TDW(Tencent distributed Data Warehouse,腾讯分布式数据仓库)基于开源软

大规模Hadoop集群实践:腾讯分布式数据仓库(TDW)

TDW 是腾讯最大的离线数据处理平台.本文主要从需求.挑战.方案和未来计划等方面,介绍了TDW在建设单个大规模集群中采取的 JobTracker 分散化和 NameNode 高可用两个优化方案. TDW(Tencent distributed Data Warehouse,腾讯分布式数据仓库)基于开源软件 Hadoop 和 Hive 进行构建,打破了传统数据仓库不能线性扩展.可控性差的局限,并且根据腾讯数据量大.计算复杂等特定情况进行了大量优化和改造. TDW服务覆盖了腾讯绝大部分业务产品,单集