堆排序
堆排序介绍
堆是一个完全二叉树:每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆;或每个节点值都小雨等于其左右孩子的值,称为小顶堆。
堆排序C#实现-顺序存储:
class Program {
static void Main (string[] args) {
int[] pData = new[] { 50, 10, 90, 30, 70, 40, 80, 60, 20 };
HeapSort(pData);
foreach (var i in pData)
{
Console.Write(i+" ");
}
Console.WriteLine();
Console.ReadKey();
}
public static void HeapSort (int[] pData) {
// 遍历数据中非叶节点,把所有子树变成子大顶堆
for (int i = pData.Length / 2; i >= 1; i--) {
int pMaxNodeNumber = i; // 最大节点编号
int pTempI = i;
while (true) {
// 把 i 节点的子树变成大顶堆
int pLeftChildNumber = pTempI * 2;
int pRightChildNumber = pLeftChildNumber + 1;
// 1、可能两个孩子都存在
// 2、可能只有一个孩子
if (pLeftChildNumber <= pData.Length && pData[pLeftChildNumber - 1] > pData[pMaxNodeNumber - 1]) {
pMaxNodeNumber = pLeftChildNumber;
}
if (pRightChildNumber <= pData.Length && pData[pRightChildNumber - 1] > pData[pMaxNodeNumber - 1]) {
pMaxNodeNumber = pRightChildNumber;
}
if (pMaxNodeNumber != pTempI) {
// 交换 i 和 pMaxNodeNumber的数据
int pTempNode = pData[pTempI - 1];
pData[pTempI - 1] = pData[pMaxNodeNumber - 1];
pData[pMaxNodeNumber - 1] = pTempNode;
pTempI = pMaxNodeNumber;
} else {
break;
}
}
}
}
堆排序C#实现-顺序存储(首尾交换,大顶堆的重新构造):
class Program {
static void Main (string[] args) {
int[] pData = new[] { 50, 10, 90, 30, 70, 40, 80, 60, 20 };
HeapSort(pData);
foreach (var i in pData) {
Console.Write(i + " ");
}
Console.WriteLine();
Console.ReadKey();
}
// 排序
public static void HeapSort (int[] pData) {
// 遍历数据中非叶节点,把所有子树变成子大顶堆
for (int i = pData.Length / 2; i >= 1; i--) {
HeapAJust(i,pData,pData.Length);
}// End For
for (int i = pData.Length; i > 1; i--) {
// 交换首位数据
int pTempNumber = pData[0];
pData[0] = pData[i - 1];
pData[i - 1] = pTempNumber;
// -------------------------------------------------------
HeapAJust(1,pData,i-1);
}
}
// 方法提取
private static void HeapAJust (int pNumberToJust, int[] pData, int pMaxNumber) {
int pMaxNodeNumber = pNumberToJust; // 最大节点编号
int pTempI = pNumberToJust;
while (true) {
// 把 i 节点的子树变成大顶堆
int pLeftChildNumber = pTempI * 2;
int pRightChildNumber = pLeftChildNumber + 1;
// 1、可能两个孩子都存在
// 2、可能只有一个孩子
if (pLeftChildNumber <= pMaxNumber && pData[pLeftChildNumber - 1] > pData[pMaxNodeNumber - 1]) {
pMaxNodeNumber = pLeftChildNumber;
}
if (pRightChildNumber <= pMaxNumber && pData[pRightChildNumber - 1] > pData[pMaxNodeNumber - 1]) {
pMaxNodeNumber = pRightChildNumber;
}
if (pMaxNodeNumber != pTempI) {
// 交换 i 和 pMaxNodeNumber的数据
int pTempNode = pData[pTempI - 1];
pData[pTempI - 1] = pData[pMaxNodeNumber - 1];
pData[pMaxNodeNumber - 1] = pTempNode;
pTempI = pMaxNodeNumber;
} else {
break;
}
}//End While
}//End HeapAJust
}