en造数据结构与算法C# 之 堆排序

堆的特点

堆排序有两个分类:大顶堆,小顶堆

比如大顶堆就是说所有根节点的值都比左右子节点大

en造数据结构与算法C# 二叉排序树 泛型类的基本构成-CSDN博客

en造数据结构与算法C# 之 二叉排序树的增/查-CSDN博客

en造数据结构与算法C# 之 二叉排序树的删除-CSDN博客

堆排序的思路

堆构成

以大顶堆为例,对于索引从0开始的数组,其实现思路如下:

堆构成,首先是找到非叶子节点的子树

关键:完全二叉树的性质

非叶子节点的索引为(0,n/2-1),向下取整

叶子节点的索引从(n/2,n-1),向下取整

之后将根节点与两个子节点比较后,看是否交换,之后依次向上找子树,不断递归调整

对于一个数组,堆构成的方法为,其中n是数组长度

cs 复制代码
  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);
  }

堆排序

这一步是在数组中利用上面的构成方法,进行堆的排序

首先,先执行一次构成堆的方法,将最大的值拿到树顶

其次,因为排序,所以需要将数值大的元素和最后一位交换

然后,将首位和末尾的数值进行交换,再进行一次堆构成的方法,并且忽略最后一位

以此类推

cs 复制代码
    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);
        }
    }

总览:

cs 复制代码
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);
        }
    }
}
相关推荐
小孟Java攻城狮3 小时前
leetcode-不同路径问题
算法·leetcode·职场和发展
查理零世4 小时前
算法竞赛之差分进阶——等差数列差分 python
python·算法·差分
小猿_006 小时前
C语言程序设计十大排序—插入排序
c语言·算法·排序算法
军训猫猫头7 小时前
52.this.DataContext = new UserViewModel(); C#例子 WPF例子
开发语言·c#·wpf
熊文豪8 小时前
深入解析人工智能中的协同过滤算法及其在推荐系统中的应用与优化
人工智能·算法
siy233311 小时前
[c语言日寄]结构体的使用及其拓展
c语言·开发语言·笔记·学习·算法
AI+程序员在路上11 小时前
C#调用c++dll的两种方法(静态方法和动态方法)
c++·microsoft·c#
吴秋霖11 小时前
最新百应abogus纯算还原流程分析
算法·abogus
灶龙12 小时前
浅谈 PID 控制算法
c++·算法
菜还不练就废了12 小时前
蓝桥杯算法日常|c\c++常用竞赛函数总结备用
c++·算法·蓝桥杯