排序算法--堆排序

    要讨论堆排序,首先就要简单的讨论一下堆这种数据结构.

    堆排序所用到的二叉堆可以用数组表示出来,而且它可以被看作是一棵完全二叉树.出了树的最后一层,其它层应当是被填满的.

    每个节点除了最后一层的叶子节点,从不同的角度观察都具备了不同的角色.假设有一个节点i,我们应当注意它产生的三个不同的角色.

    Parent(i) = i / 2;

    LeftChild(2i);

    RightChild(2i + 1);

    堆结构应当满足的性质是:

        A[Parent(i)] > A[i]

    既子节点最多只能等于父节点,而不能大于父节点.所以当有节点违反这个性质的时候就产生了一种调整的方法,使其符合堆的性质.过程就是查看节点i的LeftChild(i)和RightChild(i)是否大于节点i,如果违反了堆的性质,则把节点i和其较大的子节点交换,然后再递归的查看交换过的节点是否又违反了堆的性质,然后不停的调整,直到堆中所有的节点都没有违反堆的性质.

    完成以上的步骤以后,整个数组中的最大值就位于了根节点的位置上,一个大根堆就这样建成了.接下来我们就可以用这个大根堆来进行堆排序了.

堆排序:

算法:

    当一个大根堆建好的时候,数组中最大的节点就位于了A[1]的位置,既根节点的位置,我们把这个最大值和堆中的最后一个节点A[n]交换,并把A[n]从堆中去掉,将堆的规模减小1.堆排序的一步就完成了.同时因为交换上去的节点再一次的破坏了堆的性质,我们再从新的建立一个大根堆,完成以后,数据数组中的次大元素就位于了根节点的位置,接下来继续对它进行刚才最大元素所经历的操作,照此循环往复,就可以完成堆排序了.完成的时候,数组的第一个节点就是数据中最小的节点,最后一个是最大的节点.

代码:

 

#include  < stdio.h >
#define  Parent(i) i / 2
#define  Left(i) 2 * i
#define  Right(i) (2 * i + 1)

const   int  MAX   =   11 ;


void  Heapify( int   * A,  int  i,  int  heapSize)
{
    
int left, right, parent, largest, temp, done;
    done 
= 0;
    largest 
= -1;
    
while(Parent(i) <= heapSize && i >= Parent(i))
    
{
        left 
= Left(i);
        right 
= Right(i);
        parent 
= Parent(i);
        
if(left < heapSize && A[left] > A[i])
            largest 
= left;
        
else
            largest 
= i;
        
if(right < heapSize && A[right] > A[largest])
            largest 
= right;
        
if(largest != i)
        
{
            temp 
= A[largest];
            A[largest] 
= A[i];
            A[i] 
= temp;
        }

        i
++;
    }

}


void  buildHeap( int   * A,  int  heapSize)
{
    
int i;
    
for(i = (MAX - 1/ 2; i > 1; i--)
        Heapify(A, i, heapSize);
}


void  heapSort( int   * A)
{
    
int i, temp, heapSize;
    heapSize 
= MAX - 1;
    buildHeap(A, heapSize);
    
for(i = MAX - 1; i >= 1; i--)
    
{
        temp 
= A[i];
        A[i] 
= A[1];
        A[
1= temp;
        heapSize 
-= 1;
        Heapify(A, 
1, heapSize);
    }

}


int  main()
{
    
int A[MAX];
    
int i;
    
int nums = MAX - 1;
    printf(
"Please input %d numbers: ", nums);
    
for(i = 1; i < MAX; i++)
        scanf(
"%d"&A[i]);
    heapSort(A);
    
for(i = 1; i < MAX; i++)
        printf(
"%d ", A[i]);
    
return 0;
}

 

    堆排序的时间复杂度的上界是O(nlog2n),现在还没有明确的下界.不过实践中堆排序要比使用Sedgewick增量序列的希尔排序慢.并且因为需要不停的建堆,所以元素较少的时候不推荐用堆排序.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值