堆排序(七)
import java.util.Arrays; /** * * @author lixuwu *堆排序两步:建立堆的过程,堆的调整过程 *堆中的元素用数组来进行存储,标号从1开始;结点i的左右子树为2i和2i+1,堆的最后一个非叶结点的编号为n/2 *堆的大小即为堆中元素的个数,不等于数组的大小(这里在堆得调整过程中很重要) *对于堆的存储结构数组,第一个元素的下标为0,一般用一个特殊的数字区分,不参与堆的排序过程 */ public class HeapSort { /** * * @param array * @param i 需要调整的堆元素在数组中的位置。一般从堆顶(1)或者堆的堆的最后一个非叶节点(n/2)开始 * @param n 堆的大小,也就是堆中存储元素的个数 * * 以下向下调整的过程是建立一个大顶堆的过程,从堆中某一个位置i开始,分别与他的左右子树(2i,2i+1)进行比较, * 找出i,2i,2i+1中最大的元素t,如果最大元素t=i,结束调整。如果最大元素t !=i,则两者数值交换,i=t,继续向下调整 */ public static void siftdown(int array[],int i,int n){ int t,temp,flag=0; //flag用来标记是否需要继续向下调整 //当i结点有儿子(其实是至少有左儿子)并且需要继续调整的时候循环就执行 while(i*2<=n && flag==0){ //首先判断它和左儿子的关系,并用t记录较大结点编号 if(array[i] < array[2*i]){ t = 2*i; }else{ t = i; } //如果结点i有右儿子,再对右儿子进行讨论,如果右儿子的值更大,更新较大的结点t if(i*2+1 <=n){ if(array[t] <array[i*2+1]) t = i*2+1; } //如果发现最大的结点编号不是自己,说明子结点中有比父结点更大的。此时将父结点与子结点进行交换 if(t != i){ temp = array[i]; array[i] = array[t]; array[t] = temp; i = t; //更新i为刚才与它交换的儿子结点的编号,便于接下来继续向下调整 }else{ flag = 1; //否则说明当前的父结点已经比两个子结点都要大了,不再进行调整了 } } //end while; } //建立堆的函数 public static void creat(int array[]){ int i; int n = array.length-1; //因为堆的第一个结点编号从1开始,所有要排除数组中下标为0的那个元素 //从最后一个非叶结点n/2到第1个依次进行向下调整的过程 for(i=n/2;i>=1;i--) siftdown(array, i,n); } //堆排序:从大顶堆开始,每次将堆顶元素与堆尾元素交换,堆的大小减一,然后再调整堆顶元素。如此反复 //直到堆的大小变为1为止。此时数组中的元素就已经是排序好的了 public static void heapSort(int array[]){ int n = array.length-1; //表示堆中元素的个数 while(n>1){ int temp = array[1]; array[1] = array[n]; array[n] = temp; n--; siftdown(array, 1,n); } } public static void main(String[] args) { // TODO Auto-generated method stub int a[] ={0,2,4,1,5,3,9,7,8,6}; creat(a); heapSort(a); System.out.println(Arrays.toString(a)); } }
运行结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,让更多的人能够享受到获取知识的快乐!因为本人初入职场,鉴于自身阅历有限,所以本博客内容大部分来源于网络中已有知识的汇总,欢迎各位转载,评论,大家一起学习进步!如有侵权,请及时和我联系,切实维护您的权益!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程