算法导论笔记之堆排序

堆排序:时间复杂度nlgn堆是一种特殊的二叉树,最大堆:根节点的key大于其两个孩子节点键值,依次类推,所以最大值为根,最小值在叶子节点处ITA定义堆的数组表示法为1-10,所以a[0]暂用无处,比如,长度为10的堆,则用a[1]-a[10]表示,建立时的长度要比实际长度多1几个
摘要由CSDN通过智能技术生成

堆排序:时间复杂度nlgn


堆是一种特殊的二叉树,最大堆:根节点的key大于其两个孩子节点键值,依次类推,所以最大值为根,最小值在叶子节点处

ITA定义堆的数组表示法为1-10,所以a[0]暂用无处,比如,长度为10的堆,则用a[1]-a[10]表示,建立时的长度要比实际长度多1


几个常见操作


HEAPIFY:函数原型maxheapify(int *a,int i):表示将数组a从当前位置i开始建立最大堆(或最小堆),取左右孩子中最大值与根节点交换,并以交换后的孩子结点为i进行递归调用


BUILD-MAX-HEAP:函数原型buildMaxHeap(int *a,int length):从length/2位到第1位循环调用maxheapify函数即可,即保证最后建成的是一个最大堆


HEAP-SORT:函数原型:heapSort(int *a,int arraylength),使用前提为a已经为最大堆,此时,循环length次,每次将a[1]与a[length]交换,则保证a[length]为当前堆的最大值,然后将长度减1,通过调用maxHeapify再次使剩下部分建成最大堆,重复上面过程


优先级队列:(用堆实现)

常用的几个操作:


HEAP-MAX:直接return a[1]即可


EXACT-MAX:返回最大值,并取出最大值:返回a[1]后,将a[length]与a[1]交换,并将长度减1,最后执行maxheapify(a,1)即可,即再次建堆


HEAP-INCREASE-KEY:函数原型heapIncreaseKey(int *a,int i,int key),将a[i]的值变为key(key应比a[i]大,否则无意义):问题的关键在于a[i]的值变为key后会不会超过原来a[i]的父亲节点,因此多加一个判断和交换即可


HEAP-INSERT:函数原型:heapInsert(int *a,int key):在堆a中插入新元素key


基本思想:length++,这是必须的;将a[length]置为负无穷(即新扩充的那个位置);调用heapIncreaseKey(a,length,key)

原理:因为a[length]手动置为负无穷,所以heapIncreaseKey(a,length,key)调用后key一定比a[length]要大,因此会执行相应操作


将一个数组建最大堆并进行堆排序的实现(C++)

void exchange(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}


void maxHeapify(int *a,int i,int length)
{
int l=2*i;
int r=2*i+1;
int largest;
if(l<=length && a[l]>a[i] )
largest=l;
else
largest=i;
if(r<=length && a[r]>a[largest])
largest=r;


if(largest!=i)
{
exchange(a[i],a[largest]);
maxHeapify(a,largest,length);
}
}


void printArray(int *a,int arraylength)
{
for(int i=0;i!=arraylength;i++)
{
cout<<a[i]<<"  ";
}
cout<<endl;
}


void buildMaxHeap(int *a,int arraylength)
{
int length=arraylength-1;
for(int i=length/2;i!=0;i--)
{
maxHeapify(a,i,length);


}
}

void heapSort(int *a,int arraylength)
{
int length=arraylength-1;
for(int i=length;i!=1;i--)
{
exchange(a[i],a[1]);
length--;
maxHeapify(a,1,length);
}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值