堆排序算法原理
更多内容,前往 IT-BLOG
它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。
一、什么是堆
【1】堆是一个完全二叉树,特点是从上往下,从左往右以次排列的;
【2】在堆的数据结构中,堆中的最大值总是位于根节点,所有父节点都满足大于等于其子节点;
二、创建堆
【需求】:将下面的二叉树,变成一个平衡二叉树。
1 /** 2 * Created by Administrator on 2020/3/21 0021. 创建堆 3 */ 4 public class HeapSortDemo { 5 /**@desc 说明1 heapfy 方法 6 * @param i : 表示对那个节点进行堆的heapify 7 * @param h : 表示堆的节点个数 8 */ 9 public void heapfiy(Integer[] arr, int i, int h){ 10 //1、计算树的节点个数,减1代表下标 11 int n = h; 12 13 //递归需要定义一个出口 14 if(i >= (n-2)/2){ 15 return; 16 } 17 //计算 i 的左子树和右子树 18 int c1 = i * 2 + 1; 19 int c2 = i * 2 + 2; 20 int max = i; 21 //判断左子树是否大于 max 下标的值 22 if(c1 < n && arr[c1] > arr[max] ){ 23 max = c1; 24 } 25 26 //判断右子树是否大于 max 下标的值 27 if(c2 < n && arr[c2] > arr[max] ){ 28 max = c2; 29 } 30 31 //如果 i == max 说明就是堆,否则就递归 heapfiy 调用 32 if(max != i){ 33 swap(arr,max,i); 34 heapfiy(arr,max,h); 35 } 36 } 37 38 //说明2: 数组到序递归 heapify,从最后一个节点的parent; 39 public void build_heap(Integer arr[],int n){ 40 //确定最后一个节点的父节点 41 int parent = (n - 2) / 2; 42 //由下向上堆排序 43 for(int i = parent; i >= 0; i--){ 44 heapfiy(arr,i,n); 45 } 46 } 47 48 //数据交换 49 public void swap(Integer[] arr,int i,int n){ 50 int temp ; 51 temp = arr[i]; 52 arr[i] = arr[n]; 53 arr[n] = temp; 54 } 55 }
三、堆排序
将堆的根结点与最后一位进行交换,然后将最后一位砍断,对剩余的数组进行递归构建堆并进行首尾交换截取即可。
1 //堆排序 2 public void heapSort(Integer[] arr){ 3 //节点的个数 4 //循环构建堆对象,i表示数组参与堆的个数 5 for(int i = arr.length; i > 0; i--){ 6 build_heap(arr,i); 7 //对第一个节点和最后一个进行交换 8 swap(arr,0,i-1); 9 } 10 }