堆排序

来源:互联网 发布:赎罪 长镜头 知乎 编辑:程序博客网 时间:2024/06/08 17:59

堆排序,和选择排序同属于选择排序类型。

其整体思想为:1  将顶元素和最后一个元素互换。

                            2  不断将带排序序列构造成为大顶堆或者小顶堆。(大顶堆:每个结点的值都大于或等于其左右孩子结点的值;小顶堆:每个结点的值都小于等于其左右孩子结点的值)

                            3  堆:满足完全二叉树性质(这点很重要。构建树,大顶堆,小顶堆,都是基于完全二叉树的思想)

主要流程:选择有孩子的结点,作为开始的基准。

                    将待排序序列构建成为一个大顶堆,其实就是从下向上从右到左,将每个非中断结点(非叶结点)当做根节点,将其和其子树调整成为大顶堆。

                    构建大顶堆的过程就是不断的在结点中选择较大的结点,构建大顶堆的过程。(中心思想)

时间复杂度为:O(n log n)

                            为不稳定的排序方法。

 

//堆排序,还是有点麻烦。写程序时一定要在脑子里走下树的图,这样子不至于混乱。
public class heapSort3 {
 public static void main(String []args){
  int a[]={4,6,2,5,8,1,9,7,0,3};
  heapSort(a,a.length-1);
  for(int i=0;i<a.length;i++){
   System.out.println(a[i]);
  }
 }
 public static void heapSort(int []a,int len){
  for(int i=len/2;i>=0;i--){//首先建立一个初始的大顶堆,注意i 的初始值,和条件>=0
   heapAdjust(a,i,len);  //调整为大顶堆的三个参数,a序列,i 父母结点,len 序列长度
  }
  for(int i=len;i>=0;i--){  //建立完大顶堆后,从下向上,从左至右的对大顶堆的,最后一个元素和第一个元素进行互换,然后再调整为大顶堆,再互换,最终父母结点值大于左右孩子结点的值。
   swap(a,0,i);          //其实这里的  i 就是元素逐渐减少的堆的长度(当前调整的大顶堆的长度)
   heapAdjust(a,0,i-1);
  }
 }
 public static void heapAdjust(int a[],int parent,int len){
  int temp,j;
  temp=a[parent];//保存父母结点的值
  for(j=2*parent;j<len;j*=2){//对比父母结点和其左右结点的值得大小,找,较大的值和父母结点互换,是循环,对每个父母结点运算,直到没有符合条件的父母结点。
   if(j<len&&a[j]<a[j+1]){//左右结点比较
    ++j;//前加,先加再运算
   }
   if(temp>=a[j]){//左右结点最大值和父母结点比较
    break;
   }
   a[parent]=a[j];//本句和下句,即为将较大值进行和父母结点的互换操作,并将父母结点的值换做左或右结点互换值的位置,利用for循环继续寻找互换
   parent=j;//此处换parent值
  }
  a[parent]=temp;//互换。
 }
 public static void swap(int []a,int x,int y){
  if(x!=y){
   int temp=a[x];
   a[x]=a[y];
   a[y]=temp;
  }
 }

}

原创粉丝点击