排序算法: 堆排序法

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

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:\n", str);
    for(i=0; i<num; i++)
    {
        printf("%3d ", *(a+i));
    }

    printf("\n");
}/* ----- 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/

posted on 2014-09-23 14:02  小猩  阅读(668)  评论(0编辑  收藏  举报

导航