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/

  • 相关阅读:
    sqlplus时报Linux-x86_64 Error: 13: Permission denied
    thrift之TTransport层的缓存传输类TBufferedTransport和缓冲基类TBufferBase
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 队列操作
    Java实现 蓝桥杯 算法提高 队列操作
    Java实现 蓝桥杯 算法提高 文本加密
    Java实现 蓝桥杯 算法提高 合并石子
  • 原文地址:https://www.cnblogs.com/xiaoxing/p/3988258.html
Copyright © 2011-2022 走看看