堆排序:
如果把待排序的数据元素集合构成一个完全二叉树的结构,则每次选出一个最大(最小)的数据元素,只需比较完全二叉树的数值为高度的次数,即log2n次,所以算法的复杂度就为O(log2n)。
堆的定义:
最小堆:
保持每个节点比它的左右孩子都小;
根节点是堆中值最小的数据元素;
根节点到每个叶子节点的路径上都是递增有序的
最大堆:
保持每个节点比它的左右孩子都大;
根节点是堆中值最大的数据元素;
根节点到每个叶子节点的路径上都是递增有序的。
1.创建堆:(手画,勿嫌弃)
2.排序:
(1)堆顶a[0]元素与当前最大堆的最后一个元素交换
(2)最大堆个数减一
(3)调整堆,使之满足最大堆
public class S{
//调整堆
public void CreatHeap(int a[],int n,int h)
{
int i=h;
int j=2*i+1;
int flag=0;
int temp=a[i];
while (j<n && flag!=1)
{
if(j<n-1 && a[j]<a[j+1])
{
j++;
}
if(temp>a[j])
{
flag=1;
}
else{
a[i]=a[j];
i=j;
j=2*i+1;
}
}
a[i]=temp;
}
//创建堆
public void initCreatHeap(int a[],int n)
{
for(int i=(n-1)/2;i>=0;i--)
{
CreatHeap(a, n,i);
}
}
//排序
public void HeapSort(int []a,int n)
{
initCreatHeap(a, n);
int x=0;
for(int i=n-1;i>0;i--)
{
x++;
int temp=a[0];
a[0]=a[i];
a[i]=temp;
CreatHeap(a, i, 0);
System.out.print("第"+x+"次排序:"+" ");
for(int j=0;j<a.length;j++)
{
System.out.print(a[j]+" ");
}
System.out.println();
}
}
public static void main(String [] args)
{
int []arr={10,50,40,88,76,9,32,5};
int n=arr.length;
S s=new S();
System.out.print("最初:"+" ");
for(int i=0;i<arr.length;i++)
{
System.out.print(arr[i]+" ");
}
System.out.println();
s.HeapSort(arr, n);
System.out.print("最终排序:"+" ");
for(int i=0;i<arr.length;i++)
{
System.out.print(arr[i]+" ");
}
}
}
最好=最坏=O(n log2n)
不稳定