几种常用的高效排序(二)--堆排

这篇介绍一种稳定且高效的排序算法-----堆排序

实现并不像快排那样简单,但是更加稳定,而且因为堆这一数据结构的介绍使其更加灵活,有和其他算法嵌入使用的延展性

其实堆排原理比快排更加简单,就是建立一个堆,每次取堆顶元素,将其删除后,调整堆使其依旧具有堆的性质,也就是保证当前结构是一个完全二叉树,且儿子均小于爸爸,

也是nlog(n)的复杂度

//调整堆的函数
//因为堆是一棵完全二叉树,所以我们可以用一个数组模拟树的结构,而且空间的利用率极高。设当前节点的标号是i,那么它的左孩子就是2×i+1 ,右孩子就是左孩子+1
void heapAdjust ( int i , int n )
{
    int child;
    int nTemp;
   //因为只有堆顶符合堆的性质,下面的子树依旧符合,所以它的两个儿子一定有一个是子树中最大的,所以找出最大的和堆顶交换,直至把当前堆顶置换到符合它的位置即可
    for (; 2*i+1<n; i = child)
    {
        child = 2*i+1;
        if ( child<n-1&&strcmp(dict[array[child+1]],dict[array[child]]) > 0 ) ++child;
        if ( strcmp(dict[array[i]],dict[array[child]]) < 0 )
        {
            nTemp = array[i];
            array[i] = array[child];
            array[child] = nTemp;
        }
        else break;
    }
}
//堆排的函数
void heapSort (  int length )
{
    int temp;
    // 首先将最初的数组调整成堆,就是从叶子开始逐步向上调整,每次保证以该节点为堆顶的堆符合性质,不用考虑树是否是完全的,因为当前数组的定义方式是可以保证的
    for ( int i = length/2-1; i >= 0 ; --i )
        heapAdjust ( i , length );
  //由于堆是大顶堆,所以每次取堆顶放到数组最后,也就是最靠右的最底层的叶子节点,然后通过迭代缩进,删掉这个叶子节点,由于原来的这个节点被换到了堆顶,所以要
//重新调整堆,使堆的性质得以维持,该步操作的复杂度是log(n) 
   for ( int i = length-1; i > 0 ; --i )
    {
        temp =array[i];
        array[i] = array[0];
        array[0] = temp;
        heapAdjust (  0 , i );
    }
}

<------------想要代码的点击代码块左上角--------------------

-------------不懂的评论中提问,当天答复---------------------

void heapAdjust ( int i , int n )
{
    int child;
    int nTemp;
    for (; 2*i+1<n; i = child)
    {
        child = 2*i+1;
        if ( child<n-1&&strcmp(dict[array[child+1]],dict[array[child]]) > 0 ) ++child;
        if ( strcmp(dict[array[i]],dict[array[child]]) < 0 )
        {
            nTemp = array[i];
            array[i] = array[child];
            array[child] = nTemp;
        }
        else break;
    }
}

void heapSort (  int length )
{
    int temp;
    for ( int i = length/2-1; i >= 0 ; --i )
        heapAdjust ( i , length );
    for ( int i = length-1; i > 0 ; --i )
    {
        temp =array[i];
        array[i] = array[0];
        array[0] = temp;
        heapAdjust (  0 , i );
    }
}


你可能感兴趣的:(数据结构,C++,算法,二叉树,堆排序)