public static void HeapSort(int[] data)
{
for (int i = data.Length/2; i>=1; i--) // 遍历 这个数的 所有非叶节点,挨个把所有的字树,变成大顶堆; data.length得到 叶子的父亲
{
HeapAdjust(i, data, data.Length);
//把 二叉树 变成 大顶堆
}
//第一个 位置 和最后一个 位置进行 交换 编号和index相差1
for (int j = data.Length; j > 1; j--) //剩余 的大 顶 堆是 j 到j-1s
{ //把 编号1 和编号i 位置进行交换
//1到(i-1)构造成大顶堆
int temp1 = data[0];
data[0] = data[j - 1]; //交换结束后, 第一个结点 树 不是 打顶 堆,要重新 构造
data[j - 1] = temp1;
//构建堆
HeapAdjust(1, data, j - 1);
}
/// <summary>
/// 堆 调整,构建 堆,在 孩子节点中寻找最大的,放在父节点上 依次遍历 直到构建成大顶堆,也就是当前节点和最大节点相等的时候
/// </summary>
/// <param name="numberToAdujust"> 调整的数字</param>
/// <param name="data">数据 数组</param>
/// <param name="maxNumber">最大编号</param>
public static void HeapAdjust(int numberToAdujust,int[] data,int maxNumber)
{
int MaxNubmerNode = numberToAdujust; //保存 最大 节点的 编号;
int tempI = numberToAdujust;
while (true) //依次 与 子节点 判断
{
//节点i 变成 大顶堆
int LeftChildNumber = tempI * 2; //左子 节点
int RightChildNumber = tempI * 2 + 1;//右子节点 ;
//编号存在, 并且 数据 比 当前 结点大; 左子树
if (LeftChildNumber <= maxNumber && data[LeftChildNumber - 1] > data[MaxNubmerNode - 1]) // 节点 和 编号之间 相差 1;
{
MaxNubmerNode = LeftChildNumber; //更新这个结点的编号;
}
//同上 右子树
if (RightChildNumber <= maxNumber && data[RightChildNumber - 1] > data[MaxNubmerNode - 1]) //得到 右 子节点;
{
MaxNubmerNode = RightChildNumber; //更新右 子节点的 编号
}
//找到一个 更大的了 发现比i 更大 的子节点 把向下移动 ,交换里面的数据 , 编号比index多1 因此-1
if (MaxNubmerNode != tempI)
{
int temp = data[tempI - 1];
data[tempI - 1] = data[MaxNubmerNode - 1];
data[MaxNubmerNode - 1] = temp;
tempI = MaxNubmerNode;//再 跟新节点编号
}
else
{
break;
}
}
}
堆排序
最新推荐文章于 2023-09-21 13:21:58 发布