C#数据结构之最小堆的实现方法

C#数据结构之最小堆的实现方法

什么是最小堆?

最小堆是一种特殊的二叉树结构,它满足以下两个条件:

  1. 是一个完全二叉树。
  2. 任意节点值不大于其子节点的值。

最小堆的根节点是整个堆中最小的元素,而它的左右子节点也必定是整个堆中数值最小的元素。

最小堆的实现

实现最小堆需要用到数组和指针,以下是一个简单的最小堆类。

public class MinHeap<T> where T : IComparable<T>
{
    private T[] _heap;
    private int _size = 0;
    private const int _defaultCapacity = 32;

    public MinHeap()
    {
        _heap = new T[_defaultCapacity];
    }

    public MinHeap(int capacity)
    {
        _heap = new T[capacity];
    }

    public void Insert(T item)
    {
        if (_size == _heap.Length)
        {
            Array.Resize(ref _heap, _heap.Length * 2);
        }

        _heap[_size] = item;
        ShiftUp(_size);
        _size++;
    }

    public T Pop()
    {
        if (_size == 0)
        {
            throw new InvalidOperationException("Heap is empty.");
        }

        var item = _heap[0];
        _size--;
        _heap[0] = _heap[_size];
        _heap[_size] = default(T);
        ShiftDown(0);
        return item;
    }

    private void ShiftUp(int i)
    {
        var parent = (i - 1) / 2;
        while (i > 0 && _heap[i].CompareTo(_heap[parent]) < 0)
        {
            var tmp = _heap[i];
            _heap[i] = _heap[parent];
            _heap[parent] = tmp;
            i = parent;
            parent = (i - 1) / 2;
        }
    }

    private void ShiftDown(int i)
    {
        var left = (i * 2) + 1;
        var right = (i * 2) + 2;
        var smallest = i;

        if (left < _size && _heap[left].CompareTo(_heap[smallest]) < 0)
        {
            smallest = left;
        }

        if (right < _size && _heap[right].CompareTo(_heap[smallest]) < 0)
        {
            smallest = right;
        }

        if (smallest != i)
        {
            var tmp = _heap[i];
            _heap[i] = _heap[smallest];
            _heap[smallest] = tmp;
            ShiftDown(smallest);
        }
    }
}

这个实现拥有两个构造函数,允许你选择初始容量。Insert 和 Pop 方法分别插入和删除元素。ShiftUp 和 ShiftDown 方法分别用于维护堆的性质。

之后,可以像下面这样使用这个类:

var heap = new MinHeap<int>();
heap.Insert(3);
heap.Insert(2);
heap.Insert(1);
Console.WriteLine(heap.Pop()); // 1
Console.WriteLine(heap.Pop()); // 2
Console.WriteLine(heap.Pop()); // 3

示例说明

假设有一个需要维护单一频率数据的应用,为了合理地利用内存占用和计算性能,在频率数据已经被加载到内存中的场景,可以使用最小堆进行排序查找,缩短算法时间。以下是实现场景的粗略思路:

  1. 频率数组顺序扫描到数据,将数据一次加入最小堆;
  2. 堆满后比较堆根节点,删除堆根数据,插入新数据;
  3. 反复执行 2 步骤,最后得到排序完毕的数据,即为单一频率数据。

另一个实现场景可以是,在一个延迟加载的海量数据中,按指定大小分批序列化,存储到单独的文件,最后合并单独大小序列化文件成结果文件。在这个场景中,使用最小堆可以很好地将延迟加载的海量单一数据进行排序,便于分批序列化和合并文件操作,优化磁盘和时间性能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#数据结构之最小堆的实现方法 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • Winform ComboBox如何独立绘制下拉选项的字体颜色

    要实现Winform ComboBox独立绘制下拉选项的字体颜色,可以采用以下步骤: 1. 继承ComboBox并重写OnDrawItem方法 我们需要自定义一个ComboBox控件,继承原有的ComboBox并重写OnDrawItem方法。在这个方法中,我们可以为每个下拉选项单独设置字体颜色。 public class CustomComboBox : C…

    C# 2023年6月6日
    00
  • c#基础系列之System.String的深入理解

    C#基础系列之System.String的深入理解 前言 String 是 C# 中的一个非常重要且常用的数据类型,使用频率很高。本文主要讲解 String 的定义、初始化、赋值、整体替换、部分替换、常见方法、比较方式、特殊字符的处理等。 定义和初始化 定义一个 String 变量,可以使用以下语法: string str; 这样定义的变量不会被初始化,其值…

    C# 2023年6月7日
    00
  • C#中字符串编码处理

    C#中字符串的编码处理需要涉及到多个类和方法。下面将从以下三个方面进行详细说明: 字符集 C#中使用Unicode字符集表示字符串,同时也支持使用ASCII和UTF-8字符集。Unicode字符集定义了每个字符与二进制编码之间的映射关系。ASCII字符集是Unicode字符集的子集,只包含128个常用字符。UTF-8字符集是一种变长编码,可以用1-4个字节表…

    C# 2023年6月7日
    00
  • C#中感叹号(!) 的作用总结

    当在C#中提及感叹号(!)时,通常指的是逻辑非运算符。这个运算符常用于实现反转布尔值。 逻辑非运算符返回一个布尔值(true或false)。如果操作数为true,则该运算符返回false;如果操作数为false,则该运算符返回true。 在C#中,逻辑非运算符主要有以下两种应用: 运用于空引用类型,表示判定该对象是否为空 在C#中,操作符!被用来判断对象是否…

    C# 2023年6月6日
    00
  • C# 实现WebSocket服务端教程

    针对“C# 实现WebSocket服务端教程”,我将提供完整的攻略。下面是详细的步骤: 步骤一:创建一个空的C#控制台应用程序 可以使用Visual Studio进行创建,也可以使用命令行创建,此处不再赘述。在创建时,需要选择.NET Core 3.x或者.NET 5+作为Target Framework。 步骤二:添加NuGet包 在控制台中输入以下命令,…

    C# 2023年5月31日
    00
  • 使用C#获取远程图片 Form用户名与密码Authorization认证的实现

    下面是详细讲解 “使用C#获取远程图片Form用户名与密码Authorization认证的实现” 的攻略。 什么是远程图片Form用户名与密码Authorization认证? 在HTTP传输中,我们经常需要进行身份认证,以确保请求者有权限访问资源。其中一种传输方式是要求客户端发送用户名和密码,以验证是否有权访问远程服务器上的资源。这种身份验证方式被称为Aut…

    C# 2023年5月15日
    00
  • 关于EF的Code First的使用以及踩坑记录

    以下是关于EF的CodeFirst的使用以及踩坑记录的完整攻略: 1. 什么是EF的CodeFirst Entity Framework (EF) 是一个对象关系映射 (ORM) 框架,它允许我们使用面向对象的方式来操作数据库。Code First是EF的一种开发模式,它允许我们使用C#代码来定义实体类,然后通过EF自动生成数据库表和关系。 2. 如何使用E…

    C# 2023年5月12日
    00
  • c#多线程网络聊天程序代码分享(服务器端和客户端)

    C#多线程网络聊天程序代码分享(服务器端和客户端) 介绍 本文所分享的是使用C#编写的多线程网络聊天程序的源代码,包括服务器端和客户端代码。网络聊天程序可以实现在不同计算机之间进行即时聊天的功能,多线程可以提升程序的并发性和性能,同时使用C#编写可以大大简化代码编写过程。 实现流程 服务器端程序编写 服务器端程序的主要作用是接受用户请求,并与客户端进行通讯。…

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部