数据结构---七大排序之堆排序

任意一个数组在不创建任何额外空间的基础上该怎末实现排序呢?

其实任意一个数组都可以看成一个完全二叉树

假设现在任意给定一个数组:

【5,2,7,3,6,1,4】

步骤:

①从最后一个非叶子节点,开始进行siftDown操作,化为最大堆

②开始交换堆顶元素和最后一个元素的位置,然后继续①siftDown操作

③依次往复①和②操作,直至全部排序。

 时间复杂度:构建大顶堆的时间复杂度是O(nlogn),n是for循环,logn是构建大顶堆的方法的时间复杂度,排序的时间复杂度也是O(nlogn),所以堆排序的时间复杂度是O(nlogn)+O(nlogn),也就是O(nlogn)

 动态图解:

代码展示:



import java.util.Arrays;

/**
 * @Author qiqichongya
 * @Date 2022/8/7 15:11
 * @PackageName:SevenSort
 * @ClassName: heapSort
 * @Description: 原地堆排序
 * 

* 任意数组都可以是作为一个完全二叉树 * 1.堆化:从最后一个非叶子节点开始,进行siftDown操作 * 2.不断交换对顶元素和最后一个元素的位置,将对顶元素继续进行siftDown, * 直到数组剩下一个未排序的元素位置。 */ public class heapSort { public static void main(String[] args) { int[] arr = {19,27,13,22,3,1,6,5,4,2,110,65,70,98,72}; sort(arr); System.out.println(Arrays.toString(arr)); } public static void sort(int[] arr) { // 1.先将任意数组进行堆化,调整为最大堆 for (int i = (arr.length - 1 - 1) / 2; i >= 0; i--) { siftDown(arr, i, arr.length); } // 2.把堆顶元素和数组末尾元素交换,每次交换就表明有一个元素落到了最终位置 for (int i = arr.length - 1; i > 0; i--) { swap(i, 0, arr); siftDown(arr, 0, i); } // 3. } /** * 交换堆顶元素和数组末尾元素 * * @param i * @param j * @param arr */ private static void swap(int i, int j, int[] arr) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } /** * 元素下沉操作 * * @param arr * @param i 下沉的索引 * @param length 数组长度 */ private static void siftDown(int[] arr, int i, int length) { while (i * 2 + 1 < length) { int left = 2 * i + 1; int right = left + 1; if (arr[right] > arr[left] && right < length) { left = right; } if (arr[i] > arr[left]) { break; } else { swap(i, left, arr); i = left; } } } }

数据结构---七大排序之堆排序_第1张图片 

 

你可能感兴趣的:(数据结构)