//堆排序 public static void heapSort(int[] arr) { //构造大根堆 heapInsert(arr); int size = arr.length; while (size > 1) { //固定最大值 swap(arr, 0, size - 1); size--; //构造大根堆 heapify(arr, 0, size); } } //构造大根堆(通过新插入的数上升) public static void heapInsert(int[] arr) { for (int i = 0; i < arr.length; i ) { //当前插入的索引 int currentIndex = i; //父结点索引 int fatherIndex = (currentIndex - 1) / 2; //如果当前插入的值大于其父结点的值,则交换值,并且将索引指向父结点 //然后继续和上面的父结点值比较,直到不大于父结点,则退出循环 while (arr[currentIndex] > arr[fatherIndex]) { //交换当前结点与父结点的值 swap(arr, currentIndex, fatherIndex); //将当前索引指向父索引 currentIndex = fatherIndex; //重新计算当前索引的父索引 fatherIndex = (currentIndex - 1) / 2; } } } //将剩余的数构造成大根堆(通过顶端的数下降) public static void heapify(int[] arr, int index, int size) { int left = 2 * index 1; int right = 2 * index 2; while (left < size) { int largestIndex; //判断孩子中较大的值的索引(要确保右孩子在size范围之内) if (arr[left] < arr[right] && right < size) { largestIndex = right; } else { largestIndex = left; } //比较父结点的值与孩子中较大的值,并确定最大值的索引 if (arr[index] > arr[largestIndex]) { largestIndex = index; } //如果父结点索引是最大值的索引,那已经是大根堆了,则退出循环 if (index == largestIndex) { break; } //父结点不是最大值,与孩子中较大的值交换 swap(arr, largestIndex, index); //将索引指向孩子中较大的值的索引 index = largestIndex; //重新计算交换之后的孩子的索引 left = 2 * index 1; right = 2 * index 2; } } //交换数组中两个元素的值 public static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }
END 题外推荐 十期推荐 【291期】你了解Log4j2中RollingFile的文件滚动更新机制吗? 【292期】Linux面试最高频的5个基本问题 【293期】面试官:你知道写时复制(Copy-On-Write)在Java中是如何被应用的吗? 【294期】面试官:谈谈你对缓存的使用和理解 【295期】面试官:已经用k8s来部署运维各个微服务的组件,是否可以不用整套微服务? 【296期】面试官:详细说说对MQ消息队列的理解以及主流MQ的优缺点 【297期】面试官:为什么在new 对象里面使用自动注入对象会报空指针异常? 【298期】面试官:如何保证token的安全 【299期】面试官:详细说一说MySQL InnoDB 中意向锁的作用 【300期】面试官:Elasticsearch 是如何做到快速检索的 ? ~