堆的特点
堆排序有两个分类:大顶堆,小顶堆
比如大顶堆就是说所有根节点的值都比左右子节点大
en造数据结构与算法C# 二叉排序树 泛型类的基本构成-CSDN博客
en造数据结构与算法C# 之 二叉排序树的增/查-CSDN博客
en造数据结构与算法C# 之 二叉排序树的删除-CSDN博客
堆排序的思路
堆构成
以大顶堆为例,对于索引从0开始的数组,其实现思路如下:
堆构成,首先是找到非叶子节点的子树
关键:完全二叉树的性质
非叶子节点的索引为(0,n/2-1),向下取整
叶子节点的索引从(n/2,n-1),向下取整
之后将根节点与两个子节点比较后,看是否交换,之后依次向上找子树,不断递归调整
对于一个数组,堆构成的方法为,其中n是数组长度
static void Heapify(int[] array, int n, int i) {
int largest = i; // 初始化最大值为根节点
int left = 2 * i + 1; // 左子节点
int right = 2 * i + 2; // 右子节点
// 如果左子节点大于根节点
if (left < n && array[left] > array[largest]) {
largest = left;
}
// 如果右子节点大于最大值节点
if (right < n && array[right] > array[largest]) {
largest = right;
}
// 如果最大值不是根节点
if (largest != i) {
int swap = array[i];
array[i] = array[largest];
array[largest] = swap;
// 递归地调整受影响的子树
Heapify(array, n, largest);
}
堆排序
这一步是在数组中利用上面的构成方法,进行堆的排序
首先,先执行一次构成堆的方法,将最大的值拿到树顶
其次,因为排序,所以需要将数值大的元素和最后一位交换
然后,将首位和末尾的数值进行交换,再进行一次堆构成的方法,并且忽略最后一位
以此类推
static void HeapSorts(int[] array) {
int n = array.Length;
// 构建堆
for (int i = n / 2 - 1; i >= 0; i--) {
Heapify(array, n, i);
}
// 一个个取出元素
for (int i = n - 1; i > 0; i--) {
// 将当前堆顶(最大值)与堆的最后一个元素交换
int temp = array[0];
array[0] = array[i];
array[i] = temp;
// 调整堆
Heapify(array, i, 0);
}
}
总览:
using System;
class Program
{
static void Main()
{
int[] array = { 50, 10, 200, 30, 70, 40, 100, 60, 20, 65, 5 };
HeapSort(array);
Console.WriteLine(string.Join(", ", array));
}
static void HeapSort(int[] array)
{
int n = array.Length;
// 构建堆
for (int i = n / 2 - 1; i >= 0; i--)
{
Heapify(array, n, i);
}
// 一个个取出元素
for (int i = n - 1; i > 0; i--)
{
// 将当前堆顶(最大值)与堆的最后一个元素交换
int temp = array[0];
array[0] = array[i];
array[i] = temp;
// 调整堆
Heapify(array, i, 0);
}
}
static void Heapify(int[] array, int n, int i)
{
int largest = i; // 初始化最大值为根节点
int left = 2 * i + 1; // 左子节点
int right = 2 * i + 2; // 右子节点
// 如果左子节点大于根节点
if (left < n && array[left] > array[largest])
{
largest = left;
}
// 如果右子节点大于最大值节点
if (right < n && array[right] > array[largest])
{
largest = right;
}
// 如果最大值不是根节点
if (largest != i)
{
int swap = array[i];
array[i] = array[largest];
array[largest] = swap;
// 递归地调整受影响的子树
Heapify(array, n, largest);
}
}
}