二叉堆本质上是一种完全二叉树,分为两个类型:
1.最大堆
2.最小堆
最大堆的任意一个父节点的值,都大于或等于它左右孩子节点的值。
最小堆的任意一个父节点的值,都小于或等于它左右孩子节点的值。
二叉堆的根节点叫作堆顶。最大堆的堆顶是整个堆中最大元素;最小堆的堆顶是这个堆中最小元素。
二叉堆的自我调整:
把一个不符合堆性质的完全二叉树,调整为一个堆。
1.插入节点;2.删除节点;3.构建二叉堆。
二叉堆的代码实现:
二叉堆是一个存储在数组中的完全二叉树。
父节点下标是parent,左孩子下标为 2*parent+1,右孩子下标是 2*parent+2。
二叉堆是实现堆排序和优先队列的基础。
using System;
using System.Collections.Generic;
namespace CSharpTest01
{
class BinaryHeap
{
/// <summary>
/// 上浮 调整
/// </summary>
/// <param name="array">待调整的堆</param>
public void UpAdjust(int[] array)
{
int childIndex = array.Length - 1;
int parentIndex = (childIndex - 1) / 2;
// temp 保存插入的叶子节点值,用于最后的赋值
int temp = array[childIndex];
while (childIndex > 0 && temp < array[parentIndex])
{
// 无须真正交换,单向赋值即可
array[childIndex] = array[parentIndex];
childIndex = parentIndex;
parentIndex = (parentIndex - 1) / 2;
}
array[childIndex] = temp;
}
/// <summary>
/// 下沉 调整
/// </summary>
/// <param name="array">待调整的堆</param>
/// <param name="parentIndex">要“下沉”的父节点</param>
/// <param name="length">堆的有效大小</param>
public void DownAdjust(int[] array, int parentIndex, int length)
{
// temp 保存父节点值,用于最后的赋值
int temp = array[parentIndex];
int childIndex = 2 * parentIndex + 1;
while (childIndex < length)
{
// 如果有右孩子,且右孩子小于左孩子的值,则定位到右孩子
if (childIndex + 1 < length && array[childIndex + 1] < array[childIndex])
{
childIndex++;
}
// 如果父节点小于任何一个孩子的值,则直接跳出
if (temp <= array[childIndex])
{
break;
}
// 无须真正交换,单向赋值即可
array[parentIndex] = array[childIndex];
parentIndex = childIndex;
childIndex = childIndex * 2 + 1;
}
array[parentIndex] = temp;
}
/// <summary>
/// 构建堆
/// </summary>
/// <param name="array">待调整的堆</param>
public void BuildHeap(int[] array)
{
// 从最后一个非叶子节点开始,依次做“下沉”调整
for (int i = (array.Length-1)/2; i >=0; i--)
{
DownAdjust(array, i, array.Length);
}
}
}
class Program
{
static void Main(string[] args)
{
BinaryHeap binaryHeap = new BinaryHeap();
int[] array = new int[] { 1, 3, 2, 6, 5, 7, 8, 9, 10, 0 };
binaryHeap.UpAdjust(array);
foreach (var item in array)
{
Console.Write(item);
}
Console.WriteLine();
array = new int[] { 7, 1, 3, 10, 5, 2, 8, 9, 6 };
binaryHeap.BuildHeap(array);
foreach (var item in array)
{
Console.Write(item);
}
Console.ReadLine();
}
}
}