堆排序算法及实现

堆排序(Heapsort)

  堆排序是一种原地排序算法,在任何时候只有常数个元素存储在输入数组以外,其运行时间为O(nlgn)。
 堆数据结构被视为一颗完全二叉树,树的每个节点对应数组中该节点的值,树的每一层都是满的(最后一层可能不满)。堆的数组A具有两个属性,即数组的长度length(A)和存放在A中的堆的元素的个数heap-size[A]。树的根为A[0],给定某个节点的下标i,其父节点Parent(i),其左儿子为lchild(i)和右儿子rchild(i):
Parent(i)=i/2;
lchild(i)=2*i+1;

rchild(i)=2*i+2;

二叉堆有最大堆和最小堆之分,最大堆的左右儿子节点均小于父节点(根为最大元素),最小堆的左右儿子节点均大于父节点(根为最小元素),下面以最大堆为例:

最大堆:

MAX-HEAPIFY(A,i)
 l <- lchild(i)
 r <- rchild(i)
 if l<heap-size[A] and A[l]>A[i]
 	then  max <- l
 	else   max <- i
 if r<heap-size[A] and A[r]>A[max]
 	then   max <- r
 if max ≠ i
  	then exchange A[i] <-> A[max]
    		MAX-HEAPIFY(A,max)


建堆:

BUILD-MAX-HEAP(A)
 heap-size[A] <- length[A]
  for i <- length/2 downto 0
      do MAX-HEAPIFY(A,i)


堆排序:

HEAPSORT(A)
 BUILD-MAX-HEAP(A)
 for i<- length[A] downto 0
     do exchange A[0] <-> A[i]
            heap-size[A] <- heap-size[A]-1
            MAX-HEAPIFY(A,0)

C 语言实现代码:

#include<stdio.h>

	void Swap(int * a,int * b)
	{
		int temp=*a;
		*a=*b;
		*b=temp;
	}

	void Max_Heap(int A[],int n,int root)
	{
		int lchild=2*root+1;
		int rchild=2*root+2;
		int max=root;
		if((lchild<n)&&(A[lchild]>A[max]))
			max=lchild;
		if((rchild<n)&&(A[rchild]>A[max]))
			max=rchild;
		if(max!=root)
		{
			Swap(&A[max],&A[root]);
			Max_Heap(A,n,max);
		}
	}

	void Build_Heap(int A[],int n)
	{
		int i;
		for(i=n/2;i>=0;i--)
		{
			Max_Heap(A,n,i);
		}
	}

	void Heap_Sort(int A[],int n)
	{
		int i;
		Build_Heap(A,n);
		for(i=n-1;i>=0;i--)
		{
			Swap(&A[0],&A[i]);
			n--;
			Max_Heap(A,n,0);
		}
	}

	void main()
	{
		int j;
		int A[]={0,16,20,3,11,17,8};
		Heap_Sort(A,7);
		for(j=0;j<7;j++)
		{
			printf("%d   ",A[j]);
		}
		printf("\n\n");
		system("pause");
	}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值