【前言】:
堆排序是选择排序的一个优化,堆实际上是一棵完全二叉树,下面我们来一起分享一下吧!
【内容】:
定义:
若有一个关键字序列(k1 、k2、k3.........kn),然后满足 ki<=k2i ki>=k2i ki <=k2i 或者 ki >=k2i 其中,i=1,2,......[n/2],则成这个n个键值的序列(k1、k2、....kn)为最小堆(或最大堆)。
2.思想:
由堆排队可以知道,最小堆可以看成是一棵以k1为根的完全二叉树,在这个二叉树中,任何一个结点的值都不大于它的两个孩子的值(或有孩子结点)。最大堆则相反;
解决的问题:
(1)如何由一个初始序列建成一个堆; (2)如何在输出堆顶元素之后调整剩余元素成为一个新堆;
代码实现:
static void Main(string[] args)
{
int[] R = { 2, 5, 9, 6, 4, 7, 8, 3, 5 };
int n = R.Length;
Console.WriteLine("需要排序的数为:");
foreach (int i in R )
{
Console.Write(i+"");
}
HeapSort(R);
Console.WriteLine("排序后的队列为:");
foreach (int i in R)
{
Console.WriteLine(i+"");
}
Console.ReadKey();
}
//调整堆的过程
public static void Sift(int[] R, int k, int n)
{
int i;
int j;
int x;
int[] t;
i = k; j = 2 * i;
x= R[k];
while (j <n-1)
{
if (j < n && (R[j] > R[j +1]))
{
j++;
}
if (R[i] < R[j])
{
break;
}
else
{
R[i] = R[j]; i = j; j = 2 * i;
}
}
}
//交换堆顶元素和最后一个
public static void HeapSort(int[] R)
{
int i;
int n=R.Length;
for ( i = n / 2; i >= 0; i--)
{
Sift(R, i, n); //从第n/2个记录开始进行筛选建堆;
}
for ( i = n-1; i >= 2; i--)
{
int temp;
temp = R[i]; //满足条件,将堆顶与最后一个元素交换
R[i] = R[1];
R[1] = temp;
Sift(R, 1, i - 1); //调整R[1],使R[1],R[2].....R[i-1]变成堆
}
}