堆排序
堆的介绍:
1、 堆有最大堆和最小堆之分,当父节点大于等于任何子节点时称为最大堆,当父节点小于等于任何子节点时称为最小堆;
2、堆一般用一维数组来存储的,例如对于下标为 i 的节点 它地方父节点的下标为 (i - 1)/2 它的子节点的下标为 2*i +1 ,2*i +2
注释:大堆 k[i] >= k[2*i+1] && k[i] >= k[2*i +2] 小堆k[i] <= k[2*i+1] && k[i] <= k[2*i +2]
算法思想:
堆的创建:
1、从最后一个非叶子节点开始,进行下移操作
2、下移操作, 比较该节点与其子节点的大小,首先,比较两个子节点的大小,选下的,然后将小的与父节点进行比较;
大数下沉;
3、堆排序操作:
1)创建最小堆 结果是最小的在最前,最大的在最后
2) 把堆的最后一个数与,最开始一个数进行交换
3)打印出堆即可
算法复杂度分析:
1、调整堆 最好的情况是不需要调整 O(1) 最坏的情况 到最底层调整结束 高度为 h 堆 复杂度为 O(n)
2、 建立堆(此部分引用他人)http://www.cnblogs.com/zabery/archive/2011/07/26/2117103.html
- 建堆:每一层最多的节点个数为n1 = ceil(n/(2^(h+1))),
因此,建堆的运行时间是O(n)。
循环调堆:
- 循环调堆(代码67-74),因为需要调堆的是堆顶元素,所以运行时间是O(h) = O(floor(logn))。所以循环调堆的运行时间为O(nlogn)。
总运行时间T(n) = O(nlogn) + O(n) = O(nlogn)。对于堆排序的最好情况与最坏情况的运行时间,因为最坏与最好的输入都只是影响建堆的运行时间O(1)或者O(n),而在总体时间中占重要比例的是循环调堆的过程,即O(nlogn) + O(1) =O(nlogn) + O(n) = O(nlogn)。因此最好或者最坏情况下,堆排序的运行时间都是O(nlogn)。而且堆排序还是原地算法(in-place algorithm)。
最终可以知道 堆排序复杂度为 O(n log(n))
源代码:
#include<iostream>
#include<cstdio>
using namespace std;
void Adjustheap(int num[], int index , int nsize)
{
int nmin ; //标记最小的
while(2*index + 1< nsize) //index表示的比较的节点的位置
{
nmin = 2*index + 1; // 假设左边的最小
if(2*index + 2 < nsize )
{//如果还有右节点 找到子节点中最小的那个 赋值给min
if(num[nmin] > num[2*index + 2])
{
nmin = 2*index + 2;
}
}
if(num[nmin] > num[index])
{
//如果大数在下面,那么不用下沉
break;
}
else
{//也可以用递归去做
swap(num[index],num[nmin]);
index = nmin; //使新指针指向 index创建最小堆
}
}
}
void Printheap(char *cstring, int num[] ,int nsize )
{
int i ;
printf("%s", cstring);
for(i = 0 ; i < nsize; i++)
{
printf("%d ", num[i]);
}
printf("\n");
}
void Buildheap(int num[], int nsize)
{
int i;
for(i = nsize/2 -1; i >= 0; i-- )
{
//从最后一个不是叶子节点的位置开始建立开始过滤
Adjustheap(num, i , nsize);
}
Printheap("Build Heap : ", num , nsize);
}
void HeapSort(int num[] ,int nsize )
{
//不断的将顶元素与底部元素进行交换, 然后进行下沉操作
int length;
int i;
length = nsize;
Printheap("Before sort: ", num , nsize);
Buildheap(num, nsize); //建立堆后最后一个会是最大,第一个会是最小
for(i = length -1; i >= 0; i--)
{
swap(num[i],num[0]); //每次交换顶元素和最后一个
nsize --; //将最小的换到最后,规模减一
Adjustheap(num,0, nsize);
}
Printheap("After Heap: ", num , length);
}
int main()
{
int data[] = {6,4,1,2,8,4,7,3,0,9};
HeapSort(data, 10);
return 0;
}