/*
建堆的过程,堆调整的过程,这些过程的时间复杂度,空间复杂度,以及如何应用在海量数据Top K问题中等等
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,
并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
1---父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2---每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
堆调整就是节点下沉的过程
有最大堆和最小堆
堆排序:
数组储存成堆的形式之后,第一次将A[0]与A[n - 1]交换,
再对A[0…n-2]重新恢复堆。第二次将A[0]与A[n-2]交换,再对A[0…n-3]重新恢复堆,
重复这样的操作直到A[0]与A[1]交换。由于每次都是将最小的数据并入到后面的有序区间,
故操作完成后整个数组就有序了。
*/
#include <stdio.h>
#include <stdlib.h>
//#include <math.h>
//int parent(int);
int left(int);
int right(int);
void HeapAdjust(int [], int, int);
void BuildHeap(int [], int);
void print(int [], int);
void HeapSort(int [], int);
/*返回父节点
int parent(int i)
{
return (int)floor((i - 1) / 2); //画画二叉树就知道了 这是二叉树的特性
}
*/
/*返回左孩子节点*/
int left(int i)
{
return (2 * i + 1);
}
/*返回右孩子节点*/
int right(int i)
{
return (2 * i + 2);
}
/*对以某一节点为根的子树做堆调整(保证最大堆性质) 建的是最大堆 核心*/
void HeapAdjust(int A[], int i, int heap_size)
{
int l = left(i);
int r = right(i);
int largest; //选择最大的放到此次堆排序的最后
int temp; //交换的temp变量
if(l < heap_size && A[l] > A[i]) //在这个树中找largest
largest = l;
else
largest = i;
if(r < heap_size && A[r] > A[largest]) //上面已经判断了是不是L 不是i的右孩子就肯定是i
largest = r; //所以不需要再次赋值给i
if(largest != i) //找到largest的下标后 和根节点交换
{
temp = A[i];
A[i] = A[largest];
A[largest] = temp;
HeapAdjust(A, largest, heap_size);
}
}
/*建立最大堆*/
void BuildHeap(int A[],int heap_size)
{
for(int i = (heap_size-2)/2; i >= 0; i--) //调整堆 是每次交换两个元素,所以只要一半循环
HeapAdjust(A, i, heap_size);
}
/*输出结果*/
void print(int A[], int heap_size)
{
for(int i = 0; i < heap_size;i++)
printf("%d ", A[i]);
printf("\n");
}
/*堆排序*/
void HeapSort(int A[], int heap_size)
{
BuildHeap(A, heap_size);
int temp;
for(int i = heap_size - 1; i >= 0; i--)
{
temp = A[0];
A[0] = A[i];
A[i] = temp;
HeapAdjust(A, 0, i); //根节点和最后一个节点交换
}
print(A, heap_size);
}
/*测试,对给定数组做堆排序*/
int main(int argc, char* argv[])
{
const int heap_size = 13; //要么就把heap_size放到最上面。
int A[] = {19, 1, 10, 14, 16, 4, 7, 9, 3, 2, 8, 5, 11};
HeapSort(A, heap_size);
// system("pause");
return 0;
}
堆排序
最新推荐文章于 2023-10-06 15:32:26 发布