zoukankan      html  css  js  c++  java
  • 堆排序

    堆排序

    堆排序是直接选择排序的一种改进算法,先将数组调整成一个堆,在将堆第一个元素最小元素和待排序区间最后一个元素交换。重新调整堆,重复执行n - 1次即可得到有序数组

    具体解释代码注释中有说明,注意完全二叉树的性质如i节点的左子树节点为2 * i是从1开始,不是从0开始。实现的时候需要注意一下

    1.创建一个大根堆或者小根堆

    2.交换第一个和最后一个,调整1 ~ n - 1为大根堆

    3.交换第一个和倒数第二个,调整1 ~ n - 2为大根堆

    ...

    主要是建堆和调整堆,其中,建堆也是调用调整实现的

    HeapSort.java

     1 package com.gxf.heapsort;
     2 
     3 /**
     4  * 堆排序
     5  * 堆排序是对直接选择排序的一种改进算法
     6  * 将待排序列rec[]调整成堆,即rec[i]<=rec[2 * i] && rec[i]<=rec[2 * i + 1]
     7  * 如果将整个序列看成是遍历一棵完全二叉树得到的,这棵树的性质可以总结为根节点小于左右节点的值
     8  * 
     9  * 主要两步
    10  * 1.建堆,将带排序调整为一个堆
    11  * 2.取根节点即最小元素rec[0],将剩下的调整为一个堆,重复执行n - 1
    12  * @author Administrator
    13  *
    14  */
    15 public class HeapSort {
    16     Rec rec = new Rec();
    17     /**
    18      * 一次调整
    19      * 调整元素rec[k]满足堆的性质,end为rec最后位置, k + 1到 end满足堆的性质
    20      * 1.暂存rec[k],选出k的左右子节点2k 2k + 1中较小的min和rec[k]进行比较,如果rec[k]<min结束调整,else to 2.
    21      * 2.将min的值放到rec[k]中
    22      * 3.查看调整过后的子树是否满足堆的性质
    23      * @param rec
    24      * @param k
    25      * @param end
    26      */
    27     public void shift(Rec rec[], int k, int end){
    28         Rec temp = new Rec();//暂存rec[k]
    29         temp.key = rec[k - 1].key;
    30         int i = k;//指向当前节点
    31         int j = 2 * k;//指向左子树根节点
    32         
    33         while(j <= end){
    34             if(j < end && rec[j - 1].key > rec[j].key)//这里j要小于end
    35                 j = j + 1;//找到左右子树节点最小值得下标
    36             if(temp.key < rec[j - 1].key)//这里用的是temp,不是rec[k],因为上移的时候会覆盖掉rec[k]的值
    37                 break;//说明满足堆的性质,不用调整
    38             else{
    39                 rec[i - 1].key = rec[j - 1].key;//子节点上移
    40                 i = j;
    41                 j = 2 * i;
    42             }
    43         }
    44         rec[i - 1].key = temp.key;//调整完后,将暂存的内容放到当前节点中
    45     }
    46     
    47     /**
    48      * 对数组rec[]按关键字key堆排序
    49      * 1.建堆
    50      * 2.交换最后一个元素和堆顶元素,调整堆,重复执行n - 1次
    51      * @param rec
    52      */
    53     public void heapSort(Rec rec[]){
    54         int n = rec.length;
    55         for(int i = n / 2; i >= 1; i--){
    56             shift(rec, i , n);
    57         }//建堆
    58         System.out.println("建堆之后:");
    59         this.rec.showArray(rec);
    60         for(int i = 1; i < n; i++){
    61             Rec temp = new Rec();
    62             temp.key = rec[0].key;
    63             rec[0].key = rec[n - i].key;
    64             rec[n - i].key = temp.key;//交换堆顶和最后一个元素
    65             
    66             shift(rec, 1 , n - i);//调整第一个元素
    67             System.out.println("第" + i + "趟,完成后:");
    68             this.rec.showArray(rec);
    69         }
    70     }
    71 }

    Rec.java

    package com.gxf.heapsort;
    
    public class Rec {
        public int key;
        
        public Rec(int key){
            this.key = key;
        }
        public Rec(){
            
        }
        public void showArray(Rec rec[]){
            for(int i = 0; i < rec.length ; i++){
                
                System.out.print(rec[i].key + " ");
            }
            System.out.println();
        }
        public Rec[] getRecArray(int array[]){
            Rec result[] = new Rec[array.length];
            for(int i = 0; i < array.length; i++){
                result[i] =  new Rec(array[i]);
            }
            return result;
        }
    }

    Test.java

     1 package com.gxf.heapsort;
     2 
     3 
     4 
     5 public class Test {
     6     public static void main(String args[]){
     7         Rec rec = new Rec();
     8         HeapSort heapSort = new HeapSort();
     9         
    10         int array[] = new int[]{0, 32, 1, 34, 54, 5, 6};
    11         Rec array_rec[] = rec.getRecArray(array);
    12         System.out.println("使用堆排序之前的顺序:");
    13         rec.showArray(array_rec);
    14         
    15         heapSort.heapSort(array_rec);//堆排序
    16         
    17         System.out.println("使用堆排序之后:");
    18         rec.showArray(array_rec);
    19     }
    20 }

    ps:这里调程序的时候我将建堆后和每次调整的结果都打印出来了

  • 相关阅读:
    [转]Asp.Net 备份和恢复SQL SERVER 数据库
    alert 的封装
    using(sqlConnection conn=new sqlConnection) 中using的作用
    dotnet 上传大文件的配置的方法
    allowDefinition='MachineToApplication'
    转 Server Application Error报错信息的解决方案
    url 自动加入链接
    MVC中使用RadioButtonFor
    linux iptables squid 透明代理
    linux iptables网关配置,端口转发
  • 原文地址:https://www.cnblogs.com/luckygxf/p/4080261.html
Copyright © 2011-2022 走看看