C# 堆

C# 堆
堆是一种非常有用的数据结构,下面的C#以插入数据的方式创建最大堆,然后实现了堆的插入和删除操作。
  //构建最大堆,
    public class MyHeap
    {
        List<int> heap = new List<int>();
        int temp;
        public MyHeap()
        {
            heap.Insert(0, -1);//第0位置保存数据-1,该数据无用
        }
        public void insertData(int d)
        {
            heap.Insert(heap.Count, d);
            adjustUp(heap.Count-1);
        }
        //向上调整堆
        private void adjustUp(int position)
        {
            //当前点的父节点数据小于当前点,则需要交换当前点父节点,接下来需要递归对当前点的父节点进行操作
            if (Math.Floor((double)position / 2) > 0 && heap[(int)(Math.Floor((double)position / 2))] < heap[position])
            {
                exchange(position, (int)(Math.Floor((double)position / 2)));
                adjustUp((int)(Math.Floor((double)position / 2)));
            }
        }
        //向下调整堆
        private void adjustDown(int position)
        {
            if (position * 2 < heap.Count && heap[position] < heap[position * 2])
            {
                exchange(position, position * 2);
                adjustDown(position * 2);
            }
            else if (position * 2+1 < heap.Count && heap[position] < heap[position * 2+1])
            {
                exchange(position, position * 2+1);
                adjustDown(position * 2+1);
            }
        }
        private void exchange(int i,int j)
        {
            temp = heap[i];
            heap[i] = heap[j];
            heap[j] = temp;
        }
        //遍历找到第一个数值=d的节点i,将堆的最后一个节点挪到i处,向下递归调整i为根节点的堆
        public void deleteData(int d)
        {
            int i =0;
            for ( i = 1; i < heap.Count; i++)
            {
                if (heap[i] == d)
                    break;
            }
            if (i == heap.Count)
                return;
            else
            {
                heap[i] = heap[heap.Count - 1];
                heap.RemoveAt(heap.Count - 1);
                adjustDown(i);
            }
        }
        public void printHeap()
        {
            for (int i = 1; i < heap.Count; i++)
            {
                Console.Write(heap[i] + " ");
            }
        }
    }
下面是测试的程序:插入数据构建堆,然后删除数据。
  MyHeap myheap = new MyHeap();
            myheap.printHeap();
            myheap.insertData(45);
            myheap.insertData(36);
            myheap.insertData(18);
            myheap.insertData(53);
            myheap.insertData(72);
            myheap.insertData(30);
            myheap.insertData(48);
            myheap.insertData(93);
            myheap.insertData(15);
            myheap.insertData(35);
            myheap.printHeap();
            Console.WriteLine("");
            Console.WriteLine("删除72");
            myheap.deleteData(72);
            myheap.printHeap();
            Console.Read();

代码:http://download.youkuaiyun.com/detail/luozuolincool/7931333

04-22
### C#数据结构的实现与用法 #### 什么是(Heap)是一种特殊的完全二叉树,分为两种形式:最大和最小。在最大中,父节点的键值总是大于或等于子节点的键值;而最小则相反,父节点的键值总是小于或等于子节点的键值[^1]。 #### 的主要特性 - **完全二叉树**:除了最后一层外,其余各层都被完全填充,并且所有结点都保持最左侧排列。 - **父子关系约束**:对于任意给定索引 $i$ 的元素,在最大中满足条件 $\text{Parent}(i) \geq \text{Child}(i)$,而在最小中则是 $\text{Parent}(i) \leq \text{Child}(i)$[^4]。 #### 在 C# 中实现 虽然 .NET Framework 提供了许多内置集合类型,但它并未直接提供一个现成的类。然而,我们可以很容易地通过数组来表示并自行编写相应的逻辑操作。下面展示了一个通用的最大实现示例: ```csharp using System; using System.Collections.Generic; public class MaxHeap<T> where T : IComparable<T> { private List<T> heap = new List<T>(); public void Insert(T value) { int index = heap.Count; heap.Add(value); while (index > 0 && heap[(index - 1) / 2].CompareTo(heap[index]) < 0) { Swap(index, (index - 1) / 2); index = (index - 1) / 2; } } public T ExtractMax() { if (heap.Count == 0) throw new InvalidOperationException("The heap is empty."); T maxElement = heap[0]; heap[0] = heap[heap.Count - 1]; heap.RemoveAt(heap.Count - 1); HeapifyDown(0); return maxElement; } private void HeapifyDown(int index) { int largestIndex = GetLargestChildIndex(index); while (largestIndex != -1 && heap[largestIndex].CompareTo(heap[index]) > 0) { Swap(largestIndex, index); index = largestIndex; largestIndex = GetLargestChildIndex(index); } } private int GetLargestChildIndex(int parentIndex) { int leftChildIndex = 2 * parentIndex + 1; int rightChildIndex = 2 * parentIndex + 2; if (leftChildIndex >= heap.Count) return -1; if (rightChildIndex >= heap.Count || heap[leftChildIndex].CompareTo(heap[rightChildIndex]) > 0) return leftChildIndex; else return rightChildIndex; } private void Swap(int firstIndex, int secondIndex) { T temp = heap[firstIndex]; heap[firstIndex] = heap[secondIndex]; heap[secondIndex] = temp; } public bool IsEmpty => heap.Count == 0; } ``` 这个 `MaxHeap<T>` 泛型类实现了基本的功能——插入新项以及提取最高优先级项(即根节点),同时还包含了辅助方法来进行必要的调整以维持属性[^1]。 #### 使用实例 这里给出一段测试代码,说明如何使用上面定义好的最大类: ```csharp class Program { static void Main(string[] args) { MaxHeap<int> maxHeap = new MaxHeap<int>(); maxHeap.Insert(3); maxHeap.Insert(7); maxHeap.Insert(9); maxHeap.Insert(5); Console.WriteLine(maxHeap.ExtractMax()); // 输出: 9 Console.WriteLine(maxHeap.ExtractMax()); // 输出: 7 Console.WriteLine(maxHeap.IsEmpty); // 输出: False } } ``` 以上程序逐步向中加入几个整数,随后依次取出其中最大的两个数字,并验证剩余部分是否为空[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值