堆排序

来源:互联网 发布:淘宝商城阿依莲 编辑:程序博客网 时间:2024/05/21 10:48
package aaa;import java.util.*;/* 堆排序,可以有效的降低时间复杂度 * 建立一个大顶堆并且进行堆排序输出从小到大排序的数 * 时间复杂度为O(NlogN) * 扩展:如果要求一个数列里面的第k大的数,只需要建立一个大小为k的小顶堆,并且不断调整维护(先选三个数建堆,后面的数逐个插入堆顶并进行删除调整), * 最后输出对堆顶元素即可 * 同理,求解一个数列里面的第k小的数,只需要建立一个大小为k的大顶堆, * */public class Main {    static Scanner in = new Scanner(System.in);    static int n;    static int[] h = new int[1000];    //交换数据值    static void swap(int x ,int y){    int t;    t = h[x];    h[x] = h[y];    h[y] = t;    }    //注意:对于一个完全二叉树而言,第一个非叶子节点编号为n/2,     //构建大顶堆,从第一个非叶子节点开始逐个向下调整    static void create(){    for (int i = n/2; i >= 1; i--) {shiftDown(i);}       }    //向下调整,i为当前叶子编号    static void shiftDown(int i){    boolean f = true;//用来判断是否需要继续调整    int t ;    //如果有左子    while(i*2 <= n && f){    //和左子的值进行比较调整,更新t值    if(h[i]<h[i*2])       t = i*2;    else    t = i;    //如果有右子,和右子的值进行比较调整更新t值    if(i*2+1 <= n){       if(h[t]<h[i*2+1])              t = i*2+1;           }        //注意我们寻找的是左右子里面最大的值    //如果当前节点需要调整,交换调整       if(t!=i){       swap(t, i);        i = t;//更新i的值,以便于进行下一次调整(下一层)       }       else       f = false;//如果当前节点不需要调整,退出    }        }    //由于要按照从小到大输出,所以把节点1和节点n交换,n--的意思是最终序列里面的最后的一个数已经确定    //并且重新调整当前堆使之成为大顶堆,以此类推,每次找出当前数里面最大的数    static void heapSort(){    while(n>1){    swap(1, n);     n--;    shiftDown(1);    }       }public static void main(String[] args) {n = in.nextInt();    int k = n;//保护n的值,用于输出for (int i = 1; i <= n; i++) {h[i] = in.nextInt();  }        create();        heapSort();       for (int i = 1; i <= k; i++){  System.out.print(h[i]+" ");    }       System.out.println();}}
两个小错误:一、没有保护n的值; 二、t写成了i,求的是左右子里面最大的
原创粉丝点击