zoukankan      html  css  js  c++  java
  • 排序算法: 堆排序法

    一,使用堆排序法之前,需要了解堆的特性:

    1,堆一般都用数组的方式来存储,堆分为“最大堆”和“最小堆”;

    2,以“最大堆”为例:

     (1)一个节点最多有两个子节点,即左右节点,每个节点都是一个堆;

     (2)父节点的值不小于子节点的值;

     (3)一个i节点其父节点为(i-1)/2,左节点(2*i+1)右节点(2*i+2)

    一个最大堆例子:

     数组 int a[]:  

    83 78 81 48 17 27

    二,将一个数组形成堆(以最大堆为例)

    数组a[]:

    27 48 81 78 17 83

    形成最大堆思路:

    (1)len=6为数组长度, i=len/2=3,从第i个节点开始,将第i个节点形成最大堆,直至i<0,即到根节点;

    (2)在第i个节点中,选出子节点(2*i+1)(2*i+2)中的最大值;

    (3)父节点和子节点最大值比较,如果子节点值更大,则位置互换,否则不变;

    (4)重复前三个步骤

    图示过程: 

    注:本例len=6,i=len/2=3,由于a[3]=78无子节点,所以图例从a[2]开始展示。

    实现代码:

    /**************************************************************************************
     *  Description: 形成一个最大堆
     *   Input Args: a代表数组指针,j为要排序的数索引,num为数据长度
     *  Output Args: 得到一个最大堆
     * Return Value: 1
     *************************************************************************************/
    int slipdown (int a[], int j, int num)
    {
        int temp = a[j];
        int i;
    
        for(i=(2*j+1); i<=num; i=(2*j+1))
        {
            /* 保证左右子节点存在前提,找出最大值 */
            if(i+1<num && a[i]<a[i+1])
                i++;
    
            /* 如果子节点更大,移到父节点  */
            if(i<num && a[i]>temp)
                a[j]=a[i];
            else
                break;
            

         /* 转入子节点 */ j=i; } a[j]=temp; return 0; } /* ----- End of slipdown() ----- */

    三,堆排序

    堆建好之后堆第0个数据是堆中最大的数据,将第0个数据和最后一个数据交换之后,再次形成最大堆,直到最后堆剩余一个数。此时,得到一个由小到大的数组。如果需要得到由大到小数组,可以形成最小堆。

    实现代码:

    /**************************************************************************************
    * Description : 打印函数
    * Input Args  : a为数组指针; num为数组长度; str为传入需要指针,指向需要打印字符串
    * Output Args :
    * Return Value:
    *************************************************************************************/

    void print(int *a, int num, char *str)
    {
        int i = 0;
    
        if(num==0)
            return;
    
        printf("show the data %s structure:
    ", str);
        for(i=0; i<num; i++)
        {
            printf("%3d ", *(a+i));
        }
    
        printf("
    ");
    }/* ----- End of print()  ----- */


    /**************************************************************************************
    * Description:
    * Input Args:
    * Output Args:
    * Return Value:
    *************************************************************************************/

    int swap (int *a, int *b)
    {
      int temp;

    
    

    temp = *a;
    *a = *b;
    *b = temp;

    
    

    return 0;
    } /* ----- End of swap() ----- */

    
    
    




    /*
    ************************************************************************************* * Description: 堆排序法 * Input Args: a为数组指针, num为数组长度 * Output Args: * Return Value: *************************************************************************************/ int heap_sort (int *a, int num) { int i; if(num==0) return -1; /* make a large heap top */ for(i=num/2; i>=0; i--) slipdown(a, i, num); print(a, num, "heap");

      /* The heap sort */ for(i=num-1; i>=1; i--) { swap(&a[i], &a[0]); slipdown(a, 0, i); } return 0; } /* ----- End of heap_sort() ----- */

     参考链接:

    维基百科排序算法大全:http://zh.wikipedia.org/wiki/排序算法

    白话经典算法系列之七 堆与堆排序:http://blog.csdn.net/morewindows/article/details/6709644/

  • 相关阅读:
    windows2008R2下iis7.5中的url重写(urlrewrite)
    C#操作IIS程序池及站点的创建配置实现代码
    C#获取IP及MAC地址 方法
    linq list select用法注意事项
    c#写windows服务 小demo
    C#创建Windows Service(Windows 服务)基础教程
    C# 编写Windows Service(windows服务程序)
    C#中DataTable中的Compute方法使用收集
    SQL Delta实用案例介绍,很好的东西,帮了我不少忙
    Linq中demo,用力看看吧
  • 原文地址:https://www.cnblogs.com/xiaoxing/p/3988258.html
Copyright © 2011-2022 走看看