堆排序算法设计,源代码:
算法大致思路,每次将数据大顶堆,然后将大顶堆中的根和最后那个数交换,就可以进行一次查最大元素了,接下来再将剩下的数据再次排成大顶堆,依次循环,知道剩下最后一个元素,那么这个元素就是最小的那个崽了,至此排序完成。
在生成大顶堆的时候,可以从最后一个元素开始依次将其与父节点进行比较,我的想法是如果这个数是双数的话,那么其父节点(假设存在父节点)只有一个子节点,因此这个时候直接比较父子两个节点,如果子节点大于父节点则交换,否则不交换,计数减一。如果这个数是单数的话,说明其父节点(假设存在父节点),则说明这个父节点有两个子节点,因此比较着三个节点的值,取最大值与父节点交换(父节点最大就不用交换),依次循环,就可以将剩下的元素变成大顶堆。
此算法的时间复杂度为:nlogn.
package suanfa;
//堆排序
public class DuiPaiXu {
public static int [] num={0,5,6,8,2,4,3,15,7,1,9};
public static void main(String []args)
{
int m=num.length;
DuiPaiXu puDuipaixu=new DuiPaiXu();
while(m>1)
{
//生成大顶堆
puDuipaixu.bigDui(m-1);
puDuipaixu.change(1,m-1);
m--;
}
for(int i=1;i<num.length;i++)
{
System.out.println(num[i]+" ");
}
}
//生成大顶堆
public void bigDui(int m)
{
int a=0;
//末尾的序号为偶数,直接和父节点比较
while(m>1)
{
if(m%2==0)
{
if(num[m]>num[m/2])
{
change(m,m/2);
}
}
else
{
//末节点有一个大于父节点
if(num[m/2]<num[m]||num[m/2]<num[m-1])
{
if(num[m]>num[m-1])
{
change(m, m/2);
}
else
{
change(m-1, m/2);
}
}
}
m--;
}
}
//交换堆顶和堆末两个数字
public void change(int m,int n)
{
int a=num[m];
num[m]=num[n];
num[n]=a;
}
}