文章插图
1.3、堆排序代码实现堆排序的理解还是比较困难的,尤其是代码实现过程,下面提供两种代码实现,大家可以选择适合自己的实现方法来理解堆排序
代码实现(一)
import java.util.Arrays;public class HeapSort {public static void main(String[] args) {//升序--->大顶堆long startTime=System.currentTimeMillis();int arr[] = {5,3,7,1,4,6,2};heapSort(arr);long endTime=System.currentTimeMillis();System.out.println("程序运行时间: "+(endTime-startTime)+"ms");}//编写一个堆排序的方法public static void heapSort(int arr[]) {int temp = 0;//完成我们最终代码//将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆for(int i = arr.length / 2 -1; i >=0; i--) {adjustHeap(arr, i, arr.length);}/** 2).将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;3).重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤 , 直到整个序列有序 。*/for(int j = arr.length-1;j >0; j--) {//交换temp = arr[j];arr[j] = arr[0];arr[0] = temp;adjustHeap(arr, 0, j);}System.out.println("数组=" + Arrays.toString(arr));}//将一个数组(二叉树), 调整成一个大顶堆/*** 功能: 完成 将 以 i 对应的非叶子结点的树调整成大顶堆* 举例int arr[] = {4, 6, 8, 5, 9}; => i = 1 => adjustHeap => 得到 {4, 9, 8, 5, 6}* 如果我们再次调用adjustHeap 传入的是 i = 0 => 得到 {4, 9, 8, 5, 6} => {9,6,8,5, 4}* @param arr 待调整的数组* @param i 表示非叶子结点在数组中索引* @param length 表示对多少个元素继续调整,length 是在逐渐的减少*/public static void adjustHeap(int arr[], int i, int length) {int temp = arr[i];//先取出当前元素的值,保存在临时变量//开始调整//说明//1. k = i * 2 + 1 k 是 i结点的左子结点for(int k = i * 2 + 1; k < length; k = k * 2 + 1) {if(k+1 < length && arr[k] < arr[k+1]) { //说明左子结点的值小于右子结点的值k++; // k 指向右子结点}if(arr[k] > temp) { //如果子结点大于父结点arr[i] = arr[k]; //把较大的值赋给当前结点i = k; //!!! i 指向 k,继续循环比较} else {break;//!}}//当for 循环结束后,我们已经将以i 为父结点的树的最大值,放在了 最顶(局部)arr[i] = temp;//将temp值放到调整后的位置}}
结果:【数据结构与算法【Java】08---树结构的实际应用】

文章插图
代码实现(二)
//交换数组中的元素public static void swap(int[]num ,int i,int j) {int temp=num[i];num[i]=num[j];num[j]=temp;}//将待排序的数组构建成大根堆public static void buildbigheap(int []num,int end) {//从最后一个非叶子节点开始构建,依照从下往上,从右往左的顺序for(int i=end/2;i>=0;i--) {adjustnode(i, end, num);}}//调整该节点及其以下的所有节点public static voidadjustnode(int i,int end,int []num) {int left=2*i+1;int right=2*i+2;int big=i;//判断小分支那个是大元素if(left<end&&num[i]<num[left])i=left;if(right<end&&num[i]<num[right])i=right;if(i!=big) {//交换顺序之后需要继续校验swap(num, i, big);//重新校验,防止出现交换之后根节点小于孩子节点的情况adjustnode(i, end, num);}}public static void main(String[] args) {int []num ={5,3,7,1,4,6,2};long startTime=System.currentTimeMillis();//第一次构建大根堆buildbigheap(num, num.length);for(int j=num.length-1;j>0;j--) {System.out.print("第"+(num.length-j)+"次排序前:");for(int k=0;k<num.length;k++) {System.out.print(num[k]+" ");}//交换队头已经排序得到的最大元素与队尾元素swap(num, 0, j);System.out.print("第"+(num.length-j)+"次排序后:");for(int k=0;k<num.length;k++) {System.out.print(num[k]+" ");}System.out.println();//交换结束之后,大根堆已经被破坏,需要开始重新构建大根堆buildbigheap(num,j);}long endTime=System.currentTimeMillis();System.out.println("程序运行时间: "+(endTime-startTime)+"ms");}
结果:
文章插图
2、赫夫曼树2.1、简介1、给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl) 达到最小 , 称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍夫曼树 。
2、赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近
重要概念和举例说明
- 路径和路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径 。通中分支的数目称为路径长度 。若规定根结点的层数为 1,则从根结点到第 L 层结点的路径长度为 L-1
推荐阅读
- 1 python-数据描述与分析
- 创造与魔法最新每日礼包兑换码是多少
- 企业运维 | MySQL关系型数据库在Docker与Kubernetes容器环境中快速搭建部署主从实践
- 驱动通信:通过PIPE管道与内核层通信
- 光与夜之恋双十一礼包怎么购买
- MES系统与ERP系统信息集成有哪些原则?
- 企业MES系统与ERP信息集成要素有哪些?
- 光与夜之恋钜惠嘉年华怎么买划算
- 补充部分---ScheduledThreadPoolExecutor类分析 线程池底层原理详解与源码分析
- 驱动开发:通过ReadFile与内核层通信