堆排序

package cn.arith.zuiyou;

public class HeapSort {

 /**
堆排序是稳定log(N)复杂度的算法

堆排序需要维护的堆的性质要满足:
1.是一棵二叉树,而且是完全二叉树(除了最后一层都是满的,最后一层先把左边填满)
2.如果是最大堆,要保证父节点的值大于两个子节点的值。(最小堆同理)

二叉树的数据结构是用数组来表示的,完全二叉树的性质有 父节点坐标*2 = 左儿子坐标,
父节点坐标*2 + 1 = 右儿子坐标。


流程:
1.建立一个最大堆,让数组满足堆的性质。
2.每次取出堆顶的最大值,放到堆尾,并将堆的大小减去1,直到剩下一个元素不用排序为止。

*/
 
 int arr[]=new int[]{9,3,6,8,2,1};
 int size=arr.length;//数组长度
 public static void main(String[] args) {

  HeapSort s=new HeapSort();
  
  s.sort();//数组arr从大到小排序,arr[0]最大
 }
 
 //堆排序
 void sort(){
  buildHeap();
  int num=size;
  for(int i=num-1;i>0;i--){
   //交换两结点,小数往上移
   swap(i,0);
   size--;
   swapDown(0);
  }
  print();
 }
 /**
  * 建立小顶堆:父结点数字大于左右结点的数字
  */
 void buildHeap(){
  for(int i=size/2-1;i>=0;i--){
   swapDown(i);
  }
  System.out.print("buildHeap:");
  print();
  System.out.println();
 }
 
 void print(){
  for(int i=0;i<arr.length;i++){
   System.out.print(" "+arr[i]);
  }
 }
 
 /**
  * 下滤:最大值行下沉
  * @param index (带叶子结点的父结点的下标)
  */
 void swapDown(int index){
  System.out.print("index0="+index);
  int min;//最小值指向下标
  while(index*2+1<size){//如果存在左结点
   System.out.print("down ");
   int left=2*index+1;
   min=left;
   if(index*2+2<size){//如果存在右结点
    int right=2*index+2;
    if(arr[min]>arr[right]){
     min=right;//min指向左右结点的最小值
    }
   }
   //min与父结点index比较
   if(arr[min]<arr[index]){
    //交换两结点,小数往上移
    swap(min,index);
    index=min;
   }
   else{
    break;
   }
   print();
  }
  System.out.println();
 }
 
 //交换两结点,小数往上移
 void swap(int min,int index){
  int temp=arr[min];
  arr[min]=arr[index];
  arr[index]=temp;
 }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值