最近要准备面试,补习数据结构和算法(都是泪),在这里做一个学习笔记。
今天学习最大堆和堆排序。
最大(小)堆:
实质:逻辑结构:完全二叉树;存储结构:数组。(参考这篇文章,详细讲述了二叉树的存储结构http://www.cnblogs.com/pengyingh/articles/2396466.html);
特点:最大堆的父亲要大于等于孩子。(最小堆相反);
堆排序:一种选择排序,每次在序列中取出最大值或最小值,相比直接选择排序,堆排序体现出了数据结构的好处。
原理:利用构建的最大堆的性质,每次最大堆的堆顶元素,将堆顶元素放到堆尾,即将数组的第一个元素和最后一个元素交换;再对剩下的N-1个元素循环操作,边排序完毕;
时间复杂度:O(nlogn);(构建堆需要logn,堆排序需要n次构建);
空间复杂度:O(1);只需要一个常量单元用于交换。
堆排序不适合排序小数据量;频繁建堆。
代码实现
#include <iostream>
using namespace std;
int parent(int i)//数组存储结构,完全二叉树
{
return i/2;
}
int left(int i)
{
return i*2;
}
int right(int i)
{
return i*2+1;
}
void maxheap(int *a,int i,int length)
{
int L,R;
L=left(i);
R=right(i);
int largest;
if (L<length&&a[L-1]>a[i-1])
{
largest=L;
}
else
{
largest=i;
}
if (R<length&&a[R-1]>a[largest-1])
{
largest=R;
}
if (largest!=i)
{
int temp;
temp=a[i-1];
a[i-1]=a[largest-1];
a[largest-1]=temp;
maxheap(a,largest,length);//每次交换后,都需要对交换的孩子节点再次构建最大堆
}
}
void Max_heap(int *a,int length)
{
if (length>1)
{
for (int i=length/2;i>0;i--)
{
maxheap(a,i,length);
}
}
}
void heap_sort(int *a,int length)
{
if (length > 1)
{
for (int i=length;i>1;i--)
{
Max_heap(a,i);
int temp;
temp=a[0];
a[0]=a[i-1];
a[i-1]=temp;
}
}
}
void main()
{
int a[10]={5,3,5,8,2,9,12,78,9,2};
//Max_heap(a,10);
heap_sort(a,10);
for (int i=0;i<10;i++)
{
cout<<a[i]<<endl;
}
}