算法导论 第六章:堆排序

(二叉)堆数据结构是一种数组对象,如下图所知,他可以被视为一颗完全二叉树。

其有如下性质:

1)对于i节点(i表示下标),其父节点为Li/2」,左孩子节点为2i,右孩子节点为2i+1

2)最大堆满足:A[PARENT(i)] ≥ A[i] ;最小堆满足:A[PARENT(i)] ≤ A[i]

3)堆的高度为:Θ(lgn)

4)子数组元素A[ (Ln/2」+1)...n]是树中的所有叶子节点

维持堆的性质

以最大堆为例,当节点i违反了最大堆的性质,则需从节点i处“下降”以调整堆。伪代码如下:

其时间复杂度为:T(n)=O(h)

EG:

建堆

根据上述性质4,对于数组A,建堆伪代码如下:

其时间复杂度为:T(n)=O(n)

堆排序

伪代码如下:

其时间复杂度为:T(n)=O(nlgn)

EG:

......

堆排序完整代码如下:

#include<iostream>
#define PARENT(i) (i/2)
#define LEFT(i)   (2*i)
#define RIGHT(i)  (2*i+1)
using namespace std;

void Print(int *a,int n)
{
	for(int i=1;i<=n;i++)
		cout<<a[i]<<"   ";
	cout<<endl;
	}
int *Transform(int *a,int n)
{
  int * A=new int[n+1];
   A[0]=n;
   for(int i=0;i<n;i++)
	   A[i+1]=a[i];
   return A;	
	}
void swap(int &a,int &b)
{
	int temp;
	temp=a;
	a=b;
	b=temp;
	}
void Max_Heapify(int *A,int i)
{//adjust the heap to maintain the heap property
	int heap_size=A[0];
	int l=LEFT(i) ;   //index of i's left child
	int r=RIGHT(i);
	int largest;     //At each step,the largest of the element A[i],A[LEFT(i)]
					 //A[RIGHT(i)] is determined,and its index is stored in largest. 

	if(l<=heap_size && A[l]>A[i])
		largest	= l;
	else
		largest = i;

	if(r<=heap_size && A[r]>A[largest])
		largest = r;
	
	if(largest!=i)     //the subtree rooted at i violate the max-heap property
	{
		swap(A[i],A[largest]);
		Max_Heapify(A,largest);  //after exchanging ,the subtree rooted at largest might violate the max-heap property
		}
	}
void Build_MaxHeap(int *A)
{//Transform array A into max-heap A,where A[0]=heap-size
	int A_length=A[0];
	for(int i=A_length/2;i>=1;i--)
		Max_Heapify(A,i);	
	}
void Heap_Sorting(int *A)
{
	Build_MaxHeap(A);
	int heap_size=A[0];
	for(int i=heap_size;i>=2;i--)
	{ 
		swap(A[1],A[i]);
		heap_size--;
		A[0]=heap_size;   //After build-maxheap,A[0] store the heap-size,which is changing
		Max_Heapify(A,1);//adjust the heap to be max-heap from the root
		}
	}
int main(){
	
	int a[]={4,1,3,2,16,9,10,14,8,7};
	int n=sizeof(a)/sizeof(int);
	int *A=new int[n+1];
	cout<<"Before Sorting A[1..n]:"<<endl;
	A=Transform(a,n);   //Transform a[0...n-1] into a[1...n];a[0]=a.length
	Print(A,n);
	
	cout<<"After Heap_Sorting A[1..n]:"<<endl;
	Heap_Sorting(A);
	Print(A,n);

	return 0;
	}

运行结果:


[注:若有错误,请指正~]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值