堆排序过程:(这里选用大顶堆)
一个完整的堆排序需要经过反复的两个步骤:构造堆结构和堆排序输出。
一、构造堆结构
1)将原始的数据,按层遍历,依次放置到一个完全二叉树的各个节点中;
2)对这个完全二叉树进行编号,从根开始,按层遍历,依次编号为1、2、3、,...,n;
3)从编号为┗n/2┛的结点开始,进行“左--根--右”的父子结点值比较。大数放在父结点,小数放在子结点。
4)接着,从编号为┗n/2┛-1的结点开始,也是“左--根--右”,父大子小。
5)直到编号为1的结点,继续“左--根--右”,父大子小。
二、堆排序输出
将大顶堆中的根结点与最后的叶子结点进行交换,然后对序列中的前n-1记录进行筛选,重新把完全二叉树调整为一个“大顶堆”,如此反复,直到排序结束。
a)对于大根堆,我们采用的是从小到大输出,因此将其放到数组的末尾,如图a,结点97与结点38交换,
b)将结点38换到根结点的位置后,要从新构造堆,即使它保持大根堆的结结构,此时结点97已不在堆中。如图b
c)重复上述过程,取此时堆结构的根节点(最大值)进行交换,放在数组后面,此时结点77与结点38交换。如图c
d)然后重复将剩余的数据构造堆结构,取根结点与最后一个结点交换,将得到图d所示结果。
e)再进一步执行堆排序输出,编号1与编号3互换,得到图e结果。
,
f)对最后的两个数据进行处理,得到最终结果。
代码如下:
package cn.whut.sort;
public class HeapSort2 {
static final int SIZE=10;
/**
* 堆排序
* @param a,数组a
* @param n,个数为n
*/
static void heapSort(int a[],int n)
{
int i,j,h,k;
int t;
for(i=n/2-1;i>=0;i--) //将a[0,n-1]建成大根堆
{
while(2*i+1<n) //第i个结点有右子树
{
j=2*i+1 ;
if((j+1)<n)
{
if(a[j]<a[j+1]) //右左子树小于右子树,则需要比较右子树
j++; //序号增加1,指向右子树
}
if(a[i]<a[j]) //比较i与j为序号的数据
{
t=a[i]; //交换数据
a[i]=a[j];
a[j]=t;
i=j ; //堆被破坏,需要重新调整
}
else //比较左右子结点均大则堆未破坏,不再需要调整
{
break;
}
}
}
//输出构成的堆
System.out.print("原数据构成的堆:");
for(h=0;h<n;h++)
{
System.out.print(" "+a[h]); //输出
}
System.out.print("\n");
for(i=n-1;i>0;i--)
{
t=a[0]; //与第i个记录交换
a[0] =a[i];
a[i] =t;
k=0;
while(2*k+1<i) //第i个结点有右子树
{
j=2*k+1 ;
if((j+1)<i)
{
if(a[j]<a[j+1]) //右左子树小于右子树,则需要比较右子树
{
j++; //序号增加1,指向右子树
}
}
if(a[k]<a[j]) //比较i与j为序号的数据
{
t=a[k]; //交换数据
a[k]=a[j];
a[j]=t;
k=j ; //堆被破坏,需要重新调整
}
else //比较左右子结点均大则堆未破坏,不再需要调整
{
break;
}
}
System.out.print("第"+(n-i)+"步排序结果:"); //输出每步排序的结果
for(h=0;h<n;h++)
{
System.out.print(" "+a[h]); //输出
}
System.out.print("\n");
}
}
public static void main(String[] args)
{
int[] shuzu=new int[SIZE];
int i;
for(i=0;i<SIZE;i++)
{
shuzu[i]=(int)(100+Math.random()*(100+1)); //初始化数组
}
System.out.print("排序前的数组为:\n"); //输出排序前的数组
for(i=0;i<SIZE;i++)
{
System.out.print(shuzu[i]+" ");
}
System.out.print("\n");
heapSort(shuzu,SIZE); //排序操作
System.out.print("排序后的数组为:\n");
for(i=0;i<SIZE;i++)
{
System.out.print(shuzu[i]+" "); //输出排序后的数组
}
System.out.print("\n");
}
}
结果如下: