堆排序
2013-10-04 21:22
134 查看
堆排序,原址:http://hi.baidu.com/taozpwater/item/3995214cd22a94e6a4c0664c
1、简介
1991年计算机先驱奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德(Robert W.Floyd)和威廉姆斯(J.Williams)在1964年共同发明了著名的堆排序算法( Heap Sort )。
堆积排序(Heap sort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法。堆积树是一个近似完全二叉树的结构,并同时满足堆积属性:即子结点的键值或索引总是小于(或者大于)它的父节点。
大根堆和小根堆:根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆,又称最小堆。根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆,又称最大堆。注意:①堆中任一子树亦是堆。②以上讨论的堆实际上是二叉堆(Binary Heap),类似地可定义k叉堆。
2、堆积树节点的访问
通常堆积树(heap)是通过一维数组来实现的。在起始数组为 0 的情形中:
1)堆积树的根节点(即堆积树的最大值)存放在数组位置 1 的地方;
注意:不使用位置 0,否则左子树永远为 0[2]
2)父节点i的左子节点在位置 (2*i);
3)父节点i的右子节点在位置 (2*i+1);
4)子节点i的父节点在位置 floor(i/2);
3、算法
在堆积树(大根堆)的数据结构中,堆积树中的最大值总是位于根节点。堆积树中定义以下几种操作:
1)最大堆积调整(Max_Heapify):将堆积树的末端子结点作调整,使得子结点永远小于父结点
2)创建最大堆积(Build_Max_Heap):将堆积树所有数据重新排序
3)堆积排序(HeapSort):移除位在第一个数据的根结点,并做最大堆积调整的递归运算
4、性能分析
最差时间复杂度 O(nlogn)
最优时间复杂度 O(nlogn)[1]
平均时间复杂度 Θ(nlogn)
最差空间复杂度 O(n) total, O(1) auxiliary
最佳算法 不是
5、源码示例
#include <cstdio>
#include <cstdlib>
#include <cmath>
const int HEAP_SIZE = 13; //堆積樹大小
int parent(int);
int left(int);
int right(int);
void Max_Heapify(int [], int, int);
void Build_Max_Heap(int []);
void print(int []);
void HeapSort(int [], int);
/*父結點*/
int parent(int i)
{
return (int)(i / 2);
}
/*左子結點*/
int left(int i)
{
return 2 * i;
}
/*右子結點*/
int right(int i)
{
return (2 * i + 1);
}
/*單一子結點最大堆積樹調整*/
void Max_Heapify(int A[], int i, int heap_size)
{
int l;
int r;
l = left(i+1) - 1;
r = right(i+1) - 1;
int largest;
int temp;
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)
{
temp = A[i];
A[i] = A[largest];
A[largest] = temp;
Max_Heapify(A, largest, heap_size);
}
}
/*建立最大堆積樹*/
void Build_Max_Heap(int A[])
{
for(int i = HEAP_SIZE/2; i >= 0; i--)
{
Max_Heapify(A, i, HEAP_SIZE);
}
}
/*印出樹狀結構*/
void print(int A[])
{
for(int i = 0; i < HEAP_SIZE;i++)
{
printf("%d ", A[i]);
}
printf("\n");
}
/*堆積排序程序碼*/
void HeapSort(int A[], int heap_size)
{
Build_Max_Heap(A);
int temp;
for(int i = heap_size - 1; i > 0; i--)
{
temp = A[0];
A[0] = A[i];
A[i] = temp;
Max_Heapify(A, 0, i);
}
print(A);
}
/*輸入資料並做堆積排序*/
int main(int argc, char* argv[])
{
int A[HEAP_SIZE] = {19, 1, 10, 14, 16, 4, 7, 9, 3, 2, 8, 5, 11};
HeapSort(A, HEAP_SIZE);
system("pause");
return 0;
}
堆排序简介
1、简介1991年计算机先驱奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德(Robert W.Floyd)和威廉姆斯(J.Williams)在1964年共同发明了著名的堆排序算法( Heap Sort )。
堆积排序(Heap sort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法。堆积树是一个近似完全二叉树的结构,并同时满足堆积属性:即子结点的键值或索引总是小于(或者大于)它的父节点。
大根堆和小根堆:根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆,又称最小堆。根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆,又称最大堆。注意:①堆中任一子树亦是堆。②以上讨论的堆实际上是二叉堆(Binary Heap),类似地可定义k叉堆。
2、堆积树节点的访问
通常堆积树(heap)是通过一维数组来实现的。在起始数组为 0 的情形中:
1)堆积树的根节点(即堆积树的最大值)存放在数组位置 1 的地方;
注意:不使用位置 0,否则左子树永远为 0[2]
2)父节点i的左子节点在位置 (2*i);
3)父节点i的右子节点在位置 (2*i+1);
4)子节点i的父节点在位置 floor(i/2);
3、算法
在堆积树(大根堆)的数据结构中,堆积树中的最大值总是位于根节点。堆积树中定义以下几种操作:
1)最大堆积调整(Max_Heapify):将堆积树的末端子结点作调整,使得子结点永远小于父结点
2)创建最大堆积(Build_Max_Heap):将堆积树所有数据重新排序
3)堆积排序(HeapSort):移除位在第一个数据的根结点,并做最大堆积调整的递归运算
4、性能分析
最差时间复杂度 O(nlogn)
最优时间复杂度 O(nlogn)[1]
平均时间复杂度 Θ(nlogn)
最差空间复杂度 O(n) total, O(1) auxiliary
最佳算法 不是
5、源码示例
#include <cstdio>
#include <cstdlib>
#include <cmath>
const int HEAP_SIZE = 13; //堆積樹大小
int parent(int);
int left(int);
int right(int);
void Max_Heapify(int [], int, int);
void Build_Max_Heap(int []);
void print(int []);
void HeapSort(int [], int);
/*父結點*/
int parent(int i)
{
return (int)(i / 2);
}
/*左子結點*/
int left(int i)
{
return 2 * i;
}
/*右子結點*/
int right(int i)
{
return (2 * i + 1);
}
/*單一子結點最大堆積樹調整*/
void Max_Heapify(int A[], int i, int heap_size)
{
int l;
int r;
l = left(i+1) - 1;
r = right(i+1) - 1;
int largest;
int temp;
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)
{
temp = A[i];
A[i] = A[largest];
A[largest] = temp;
Max_Heapify(A, largest, heap_size);
}
}
/*建立最大堆積樹*/
void Build_Max_Heap(int A[])
{
for(int i = HEAP_SIZE/2; i >= 0; i--)
{
Max_Heapify(A, i, HEAP_SIZE);
}
}
/*印出樹狀結構*/
void print(int A[])
{
for(int i = 0; i < HEAP_SIZE;i++)
{
printf("%d ", A[i]);
}
printf("\n");
}
/*堆積排序程序碼*/
void HeapSort(int A[], int heap_size)
{
Build_Max_Heap(A);
int temp;
for(int i = heap_size - 1; i > 0; i--)
{
temp = A[0];
A[0] = A[i];
A[i] = temp;
Max_Heapify(A, 0, i);
}
print(A);
}
/*輸入資料並做堆積排序*/
int main(int argc, char* argv[])
{
int A[HEAP_SIZE] = {19, 1, 10, 14, 16, 4, 7, 9, 3, 2, 8, 5, 11};
HeapSort(A, HEAP_SIZE);
system("pause");
return 0;
}