您的位置:首页 > 其它

堆排序

2017-09-30 21:58 120 查看
【前言】:

堆排序是选择排序的一个优化,堆实际上是一棵完全二叉树,下面我们来一起分享一下吧!


【内容】:

定义:

若有一个关键字序列(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]变成堆

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: