堆结构和堆排序

java 复制代码
import java.io.*;
public class Main{
    public static int MAXN = 100001;
    public static int[] arr = new int[MAXN];
    public static int n;

    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader (new InputStreamReader(System.in));
        StreamTokenizer in = new StreamTokenizer(br);

        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

        in.nextToken();
        n = (int)in.nval;

        for(int i = 0;i < n;i++){
            in.nextToken();
            arr[i] = (int)in.nval;
        }

        //堆排序
         heapSort1(arr);
		// heapSort2(arr);
        //输出排序后的数组
        for(int i = 0;i< n-1;i++){
            out.print(arr[i] +" ");
        }
        out.print(arr[n-1]);

        out.flush();
        out.close();
        br.close();
    }


    //heapInsert (i位置的数,向上调整大根堆)
    public static void heapInsert(int i){
        while(arr[i] > arr[(i-1)/2]){
            swap(arr,i,(i-1)/2);
            i = (i-1)/2;
        }
    }   
    //heapify (i位置的数,向下调整大根堆)
    //当前堆的大小为size
    public static void heapify(int i,int size){
        int l = i*2 +1;
        while(l<size){
             //比较i的左孩子2i+1 和 右孩子2i+2,哪个大,选出更大的孩子下标
           int best = (l + 1)<size && arr[l] < arr[l+1] ? (l+1) : l;

            //再比较i和更大的孩子之间哪个大
            best = arr[i] >arr[best] ? i : best;
            if(best == i){
                break;
            }
            swap(arr ,i , best);
            i = best;
            l = i*2 +1;  
        }
    }
    
    //heapSort1为从顶到底建立大根堆然后排序
    //从顶到底建立大根堆 O(n*logn)
    //依次弹出堆内最大值并排好序O(n*logn)
    //整体时间复杂度O(n*logn)
    public static void heapSort1(int arr[]){
        for(int i=0;i<n;i++){
            heapInsert(i);
        }
        int size = n;
        while(size>1){
            swap(arr,0,--size);
            heapify(0,size);
        }
    }
    //heapSort2为从底到顶建堆然后排序
    //从底到顶建立大根堆O(n)
    //依次弹出堆内最大值并排好序 O(n*logn)
    //整体时间复杂度O(n*logn)
    public static void heapSort2(int arr[]){
        for(int i = n -1;i>=0;i--){
            heapify(i,n);
        }
        int size = n;
        while (size > 1) {
			swap(arr,0, --size);
			heapify(0, size);
		}
    }

    //swap函数
    public static void swap(int[] arr,int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
相关推荐
艾莉丝努力练剑9 分钟前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
武子康1 小时前
Java-72 深入浅出 RPC Dubbo 上手 生产者模块详解
java·spring boot·分布式·后端·rpc·dubbo·nio
_殊途2 小时前
《Java HashMap底层原理全解析(源码+性能+面试)》
java·数据结构·算法
椰椰椰耶3 小时前
【Spring】拦截器详解
java·后端·spring
没有bug.的程序员4 小时前
JAVA面试宝典 - 《MyBatis 进阶:插件开发与二级缓存》
java·面试·mybatis
没有羊的王K5 小时前
SSM框架学习——day1
java·学习
珊瑚里的鱼5 小时前
LeetCode 692题解 | 前K个高频单词
开发语言·c++·算法·leetcode·职场和发展·学习方法
又菜又爱coding5 小时前
安装Keycloak并启动服务(macOS)
java·keycloak
不知道叫什么呀6 小时前
【C】vector和array的区别
java·c语言·开发语言·aigc
wan_da_ren6 小时前
JVM监控及诊断工具-GUI篇
java·开发语言·jvm·后端