C#实现优先队列和堆排序

C#实现优先队列和堆排序攻略

什么是优先队列?

优先队列(Priority Queue)是在数据结构中使用频率很高的一种类型,它的主要特点是能够在数据插入时将数据进行优先级的排序。

并且每次取出数据时取的是优先级最高的数据。

通常情况下我们使用最大堆来实现优先队列。

最大堆是一种特殊的堆,它的特点是每个结点都大于等于它的子结点。

什么是堆排序?

堆排序是一种排序算法,它通过建立最大堆(或最小堆)来实现排序。排序的过程分两步:第一步是通过建立最大堆,将元素最大的元素交换到第一位(或最小堆元素交换到末位)。第二步是将其余无序元素继续建立最大堆,直到无序的元素只剩最后一个,排序完成。

实现优先队列和堆排序

1. 实现最大堆

最大堆可以用数组来实现。

数组下标从0开始,节点i的左儿子为2i+1,右儿子为2i+2,父节点为(i-1)/2。

class MaxHeap<T> where T : IComparable<T>
{
    private List<T> Heap;

    public MaxHeap()
    {
        Heap = new List<T>();
    }

    public void Insert(T item)
    {
        Heap.Add(item);
        int n = Heap.Count - 1;
        while (n != 0 && Heap[n].CompareTo(Heap[(n - 1) / 2]) > 0)
        {
            T temp = Heap[n];
            Heap[n] = Heap[(n - 1) / 2];
            Heap[(n - 1) / 2] = temp;
            n = (n - 1) / 2;
        }
    }

    public T RemoveMax()
    {
        int n = Heap.Count - 1;
        T max = Heap[0];
        Heap[0] = Heap[n];
        Heap.RemoveAt(n);
        n--;
        int i = 0, j = 1;
        while (j <= n)
        {
            if (j < n && Heap[j].CompareTo(Heap[j + 1]) < 0)
            {
                j++;
            }
            if (Heap[i].CompareTo(Heap[j]) < 0)
            {
                T temp = Heap[i];
                Heap[i] = Heap[j];
                Heap[j] = temp;
            }
            else
            {
                break;
            }
            i = j;
            j = i * 2 + 1;
        }
        return max;
    }
}

2. 实现优先队列

使用最大堆实现优先队列。

class PriorityQueue<T> where T : IComparable<T>
{
    private MaxHeap<T> Heap;

    public PriorityQueue()
    {
        Heap = new MaxHeap<T>();
    }

    public void Enqueue(T item)
    {
        Heap.Insert(item);
    }

    public T Dequeue()
    {
        return Heap.RemoveMax();
    }
}

3. 实现堆排序

使用前面实现的最大堆实现堆排序。

class HeapSort<T> where T : IComparable<T>
{
    private static void Heapify(List<T> list)
    {
        int n = list.Count - 1;
        int i = (n - 1) / 2;
        while (i >= 0)
        {
            int maxIndex = i;
            int j = i * 2 + 1;
            while (j < n)
            {
                if (j + 1 < n && list[j].CompareTo(list[j + 1]) < 0)
                {
                    j++;
                }
                if (list[maxIndex].CompareTo(list[j]) < 0)
                {
                    maxIndex = j;
                }
                j = j * 2 + 1;
            }
            if (maxIndex != i)
            {
                T temp = list[i];
                list[i] = list[maxIndex];
                list[maxIndex] = temp;
            }
            i--;
        }
    }

    public static List<T> Sort(List<T> list)
    {
        int n = list.Count - 1;
        int i = n;
        while (i > 0)
        {
            T temp = list[0];
            list[0] = list[i];
            list[i] = temp;
            i--;
            Heapify(list.GetRange(0, i + 1));
        }
        return list;
    }
}

4. 示例说明

示例1:使用优先队列实现数组中最小的k个数

public static List<int> GetLeastNumbers(int[] arr, int k)
{
    PriorityQueue<int> pq = new PriorityQueue<int>();
    foreach (int i in arr)
    {
        if (pq.GetCount() < k || i < pq.Peek())
        {
            pq.Enqueue(i);
        }
        if (pq.GetCount() > k)
        {
            pq.Dequeue();
        }
    }
    return pq.GetList();
}

示例2:使用堆排序对数组进行排序

List<int> list = new List<int>() {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
list = HeapSort<int>.Sort(list);
foreach (int i in list)
{
    Console.Write($"{i} ");
}

总结

通过本文的介绍,我们了解了优先队列和堆排序的原理,并通过C#完成了基本的实现。

需要注意的地方是在实现最大堆和堆排序时,数组下标和计算有些不同,需要结合代码仔细理解。除此之外,最大堆和堆排序还有其他更高效、更复杂的实现方式,读者可以自行查阅学习。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#实现优先队列和堆排序 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • JS栈stack类的实现与使用方法示例

    JS栈Stack类的实现与使用方法示例 一、栈的概念 栈(stack)是一种线性数据结构,它有两个主要操作:入栈(push)和出栈(pop)。栈的特点是先进后出(FILO,First In, Last Out)。从数据结构的角度来说,栈是在同一端进行插入和删除操作的一种数据结构。该端被称为栈顶,相对地,把另一端称为栈底。 在计算机科学中,栈具有非常重要的作用…

    算法与数据结构 2023年5月19日
    00
  • C语言实现经典排序算法的示例代码

    对于C语言实现经典排序算法的示例代码,我们可以分为以下几个步骤: 1. 确定排序算法 首先需要明确使用哪种排序算法。常见的排序算法包括:冒泡排序、插入排序、选择排序、快速排序、归并排序等等。每种算法的思想和具体实现方式也有所不同。在确定算法的选择时,需要根据具体的场景和需求来进行选择。 2. 编写排序函数 确定排序算法后,需要实现一个函数用于进行排序。该函数…

    算法与数据结构 2023年5月19日
    00
  • 图解Java排序算法之快速排序的三数取中法

    图解Java排序算法之快速排序的三数取中法 什么是快速排序 快速排序是一种常见的排序方法,它的特点是在待排序的记录序列中,通过一趟排序将待排序的记录分割成独立的两部分,其中一部分的记录关键字均比另一部分的关键字小。 快速排序的基本流程 快速排序的基本流程如下: 从数列中挑出一个元素,称为“基准”(pivot)。 对数列重新排序,将比基准值小的元素放在基准前面…

    算法与数据结构 2023年5月19日
    00
  • c++冒泡排序详解

    c++冒泡排序详解 本文将对c++中的冒泡排序算法进行详解,并提供两个示例以方便读者理解。 冒泡排序的原理 冒泡排序算法通过不断比较相邻两个元素的大小,如果发现顺序不对就交换它们的位置,经过一次比较后就能确定一个元素的最终位置,再对剩余未排序的元素重复进行相同的操作,直到所有元素按照大小顺序排列完成。它的名字“冒泡”的意思即为像水泡一样,大的元素会一步一步向…

    算法与数据结构 2023年5月19日
    00
  • Java排序之冒泡排序的实现与优化

    Java排序之冒泡排序的实现与优化 冒泡排序基本原理 冒泡排序是一种简单的排序算法,其基本思想是通过比较相邻的元素,将较大的数交换到右边,较小的数交换到左边。这样每一轮交换后,未排序的数列中的最大元素就被移动到了最右边,因此被称为“冒泡排序”。 基本算法实现 下面是基本的冒泡排序算法实现: public static void bubbleSort(int[…

    算法与数据结构 2023年5月19日
    00
  • 可能是你看过最全的十大排序算法详解(完整版代码)

    针对“可能是你看过最全的十大排序算法详解(完整版代码)”这篇文章,下面是详细的攻略: 标题 首先,该文章的标题是:可能是你看过最全的十大排序算法详解(完整版代码) 文章简介 其次,在文章简介中,作者提到该篇文章是一个完整介绍了十大排序算法并且附有代码实现的文章,可以帮助读者了解这些排序算法的原理和代码实现。 内容 文章的主体部分是对十大排序算法进行详细的讲解…

    算法与数据结构 2023年5月19日
    00
  • javascript中可能用得到的全部的排序算法

    Javascript中可能用得到的全部排序算法 在JavaScript中,排序算法是非常常见和重要的。因为在编写程序时,我们经常需要对数组、集合等数据结构进行排序操作。接下来,我将按照常用的一些排序算法逐一介绍。 冒泡排序(Bubble Sort) 冒泡排序是一种简单的交换排序算法。它通过相邻两个元素的比较和交换来排序。每一轮比较都会将最大的元素沉到最底部。…

    算法与数据结构 2023年5月19日
    00
  • JS实现的数组全排列输出算法

    JS实现的数组全排列输出算法,一般使用递归实现,具体步骤如下: 步骤一:编写递归函数 首先我们需要定义一个递归函数 permutation,它的输入参数为两个数组: function permutation(arr, result = []) { // … } 其中,arr 是待排列的数组,result 是排列结果。注意,result 是一个可选参数,第…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部