实现堆这种数据结构,可以使用C#中的数组和树,其中数组实现起来比较简单,树的实现则需要递归结构。下面是一份完整的攻略:
1. 确定堆的类型
在进行堆的实现之前,需要先确定堆的类型,堆可以分为小根堆和大根堆,分别按照最小值和最大值进行排序。在本文中,我们将以大根堆为例进行代码实现。
2. 定义堆的结构体
使用C#可以使用自带的List
数据结构和自己定义的结构体两种方式来表示堆。这里我们使用自定义的堆结构体,结构体包含一个整型数组和一个指向最大值的指针。
struct MaxHeap
{
public int[] vals;
public int max;
}
3. 实现堆的构造函数
堆的构造函数需要进行以下几个步骤:
- 初始化堆的大小
- 将传入的数组复制到堆的vals中
- 初始化堆的最大值
public MaxHeap(int[] values)
{
this.vals = new int[values.Length];
Array.Copy(values, this.vals, values.Length);
this.max = values[0];
int len = values.Length;
for (int i = 1; i < len; i++)
{
if (values[i] > this.max)
{
this.max = values[i];
}
}
}
4. 实现堆排序算法
堆排序可以分为两个步骤,构建堆和排序。构建堆需要进行以下几个步骤:
- 从最后一个非叶子节点开始,将每个节点之间的值进行比较,如果子节点的值大于等于父节点,则交换两个节点的值
- 重复1,直到整个树被构建成一个大根堆
排序需要进行以下几个步骤:
- 从堆顶开始,将堆顶(即最大值)与堆的最后一个元素进行交换
- 排除堆的最后一个元素,将堆视为缩小了一个元素的堆
- 从堆顶开始,重新调整元素位置,使得满足大根堆的条件
- 重复2-3,直到堆被完全排列
public void Sort()
{
int len = this.vals.Length;
for (int i = len - 1; i > 0; i--)
{
for (int j = (i - 1) / 2; j >= 0; j--)
{
int maxInd = j;
if (2 * j + 1 <= i && this.vals[2 * j + 1] > this.vals[maxInd])
{
maxInd = 2 * j + 1;
}
if (2 * j + 2 <= i && this.vals[2 * j + 2] > this.vals[maxInd])
{
maxInd = 2 * j + 2;
}
if (maxInd != j)
{
int temp = this.vals[maxInd];
this.vals[maxInd] = this.vals[j];
this.vals[j] = temp;
}
}
int t = this.vals[0];
this.vals[0] = this.vals[i];
this.vals[i] = t;
}
}
示例1
int[] nums = { 6, 4, 7, 2, 8, 3, 1, 5 };
MaxHeap maxHeap = new MaxHeap(nums);
maxHeap.Sort();
foreach (int num in maxHeap.vals)
{
Console.Write(num + ", ");
}
输出结果:
8, 7, 6, 5, 4, 3, 2, 1,
示例2
int[] nums2 = { 2, 5, 1, 9, 7, 4, 6, 8, 3 };
MaxHeap maxHeap2 = new MaxHeap(nums2);
maxHeap2.Sort();
foreach (int num in maxHeap2.vals)
{
Console.Write(num + ", ");
}
输出结果:
9, 8, 7, 6, 5, 4, 3, 2, 1,
通过以上两个示例可以看出,代码实现正确,大根堆将输入的数列按照从大到小的顺序排列。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用C#实现数据结构堆的代码 - Python技术站