C#堆排序算法

举报
Rolle 发表于 2024/10/31 00:03:53 2024/10/31
【摘要】 堆排序(Heap Sort)是一种基于比较的排序算法,利用了二叉堆的数据结构。在堆排序中,我们首先将待排序的数组构建成一个最大堆(或最小堆),然后逐个从堆中取出最大的元素(或最小的元素),将其放到数组的末尾,同时重新调整剩余元素构成的堆,直到堆中没有元素为止。堆排序的基本原理堆排序的基本思想是:将待排序序列构造成一个最大堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时...

堆排序(Heap Sort)是一种基于比较的排序算法,利用了二叉堆的数据结构。在堆排序中,我们首先将待排序的数组构建成一个最大堆(或最小堆),然后逐个从堆中取出最大的元素(或最小的元素),将其放到数组的末尾,同时重新调整剩余元素构成的堆,直到堆中没有元素为止。

堆排序的基本原理
堆排序的基本思想是:将待排序序列构造成一个最大堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾元素就是序列中的最大值。然后将剩余的 n-1 个序列重新构造成一个最大堆,这样会得到 n 个元素中第二大的元素,再将其放到已排序序列的末尾。如此反复,直到整个序列有序。

堆排序的算法步骤
将无序序列构建成一个堆,根据升序降序需求选择最大堆或最小堆。
依次从堆中取出最大的元素(或最小的元素),将其放到数组的末尾。
重新调整剩余元素构成的堆,使其满足堆的性质。
重复步骤 2 和 3,直到堆中没有元素。
堆排序的C#实现
下面是一个堆排序算法的C#实现示例:
using System;

class Program
{
// 堆排序
static void HeapSort(int[] arr)
{
int n = arr.Length;

    // 构建最大堆
    for (int i = n / 2 - 1; i >= 0; i--)
    {
        Heapify(arr, n, i);
    }

    // 依次取出堆顶元素并调整堆
    for (int i = n - 1; i > 0; i--)
    {
        // 交换堆顶元素与末尾元素
        int temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;

        // 调整堆
        Heapify(arr, i, 0);
    }
}

// 调整堆
static void Heapify(int[] arr, int n, int i)
{
    int largest = i; // 初始化最大元素为根节点
    int left = 2 * i + 1; // 左子节点
    int right = 2 * i + 2; // 右子节点

    // 如果左子节点比根节点大,则更新最大元素
    if (left < n && arr[left] > arr[largest])
    {
        largest = left;
    }

    // 如果右子节点比最大元素还大,则更新最大元素
    if (right < n && arr[right] > arr[largest])
    {
        largest = right;
    }

    // 如果最大元素不是根节点,交换它们,并继续调整堆
    if (largest != i)
    {
        int temp = arr[i];
        arr[i] = arr[largest];
        arr[largest] = temp;

        Heapify(arr, n, largest);
    }
}

static void Main()
{
    int[] arr = { 12, 11, 13, 5, 6, 7 };
    int n = arr.Length;

    Console.WriteLine("Given array is ");
    foreach (int value in arr)
    {
        Console.Write(value + " ");
    }

    HeapSort(arr);

    Console.WriteLine("\nSorted array is ");
    foreach (int value in arr)
    {
        Console.Write(value + " ");
    }
}

}
在这个示例中,我们首先定义了一个未排序的整数数组arr。然后,我们使用HeapSort方法对数组进行排序。HeapSort方法首先通过Heapify方法将数组构建成一个最大堆,然后依次取出堆顶元素并调整堆,直到堆中没有元素。

堆排序的性能分析
堆排序的时间复杂度在所有情况下都是O(n log n),这是因为无论输入数据如何,构建堆、调整堆和取出堆顶元素的操作都需要这个数量级的时间。堆排序的空间复杂度是O(1),因为它是一种原地排序算法,不需要额外的存储空间。

堆排序的优化
尽管堆排序的时间复杂度较高,但我们可以通过一些技巧来优化它。例如,我们可以使用非递归的方式来实现Heapify方法,以减少递归调用的开销。

下面是一个优化后的堆排序算法的C#实现示例:
using System;

class Program
{
static void HeapSort(int[] arr)
{
int n = arr.Length;

    for (int i = n / 2 - 1; i >= 0; i--)
    {
        HeapifyNonRecursive(arr, n, i);
    }

    for (int i = n - 1; i > 0; i--)
    {
         Swap(arr, 0, i);
        HeapifyNonRecursive(arr, i, 0);
    }
}

static void HeapifyNonRecursive(int[] arr, int n, int i)
{
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;

    if (left < n && arr[left] > arr[largest])
    {
        largest = left;
    }

    if (right < n && arr[right] > arr[largest])
    {
        largest = right;
    }

    if (largest != i)
    {
        Swap(arr, i, largest);
        HeapifyNonRecursive(arr, n, largest);
    }
}

static void Swap(int[] arr, int i, int j)
{
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

// ... Main 方法和其他之前相同的代码 ...

}
在这个优化后的示例中,我们引入了非递归的方式来实现Heapify方法,以减少递归调用的开销。

堆排序的应用场景
堆排序适用于各种规模的数据排序,特别是当数据量较大时。由于堆排序在所有情况下的时间复杂度都是O(n log n),它在实际应用中非常受欢迎,如操作系统的进程调度、数据库的索引和优先队列的实现。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。