堆排序算法Java

基本原理

1):将带排序的序列构造成一个大顶堆,根据大顶堆的性质,当前堆的根节点(堆顶)就是序列中最大的元素

2):将堆顶元素和最后一个元素交换,然后将剩下的节点重新构造成一个大顶堆;

3):重复步骤2

 小知识点

大顶堆:在完全二叉树的基础上,每个结点的值都大于或等于其左右孩子结点的值

小顶堆:在完全二叉树的基础上,每个结点的值都小于或等于其左右孩子结点的值

完全二叉树:完全二叉树是一种特殊的二叉树。从上到下,从左到右,每一层的节点都是满的,最下边一层所有的节点都是连续集中在最左边

步骤

第一步:构建大顶堆

一:将无序的数组画出来一个二叉树,开始构建大顶堆

堆排序算法Java_第1张图片

 二:8是3的左孩子 父亲(parent)没有左孩子(lChild)大所以二者进行交换,

堆排序算法Java_第2张图片

 三:17比他兄弟小让左孩子(LChild)和父亲(parent)交换

堆排序算法Java_第3张图片

四 :20比他兄弟和父亲都大,lChild和parent互换

堆排序算法Java_第4张图片

 五:16与他的孩子又不满足条件,与又孩子互换

堆排序算法Java_第5张图片

 

 大顶堆完成

 第二步:将堆顶元素和最后一个元素进行交换,然后将剩下的节点重新构造成一个大顶堆

 

 堆排序算法Java_第6张图片

 堆排序算法Java_第7张图片

 重复

堆排序算法Java_第8张图片

 堆排序算法Java_第9张图片

 重复

堆排序算法Java_第10张图片

 堆排序算法Java_第11张图片

 重复

堆排序算法Java_第12张图片

 堆排序算法Java_第13张图片

 重复得出结果

 堆排序算法Java_第14张图片

 

代码

public class HeapSort {
	  public static void main(String[] args) {
      int[] arr = {16, 7, 3, 20, 17, 8};
      heapSort(arr);
      for (int i : arr) {
          System.out.print(i + " ");
      }
  }
  /**
   * 创建堆,
   * @param arr 待排序列
   */
  private static void heapSort(int[] arr) {
      //创建堆(这个地方可以先讲解一下)
      for (int i = arr.length - 1; i >= 0; i--) {
          //从第一个非叶子结点从下至上,从右至左调整结构
          adjustHeap(arr, i, arr.length);
      }
      //调整堆结构+交换堆顶元素与末尾元素
      for (int i = arr.length - 1; i > 0; i--) {
          //将堆顶元素与末尾元素进行交换
          int temp = arr[i];
          arr[i] = arr[0];
          arr[0] = temp;
          //重新对堆进行调整
          adjustHeap(arr, 0, i);
      }
  }
  /**
   * 调整堆
   * @param arr 待排序列
   * @param parent 父节点
   * @param length 待排序列尾元素索引
   */
  private static void adjustHeap(int[] arr, int parent, int length) {
      //将temp作为父节点
      int temp = arr[parent];
      //左孩子
      int lChild = 2 * parent + 1;
      while (lChild < length) {
          //右孩子
          int rChild = lChild + 1;
          // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
          if (rChild < length && arr[lChild] < arr[rChild]) {
              lChild++;
          }
          // 如果父结点的值已经大于孩子结点的值,则直接结束
          if (temp >= arr[lChild]) {
              break;
          }
          // 把孩子结点的值赋给父结点
          arr[parent] = arr[lChild];
          //选取孩子结点的左孩子结点,继续向下筛选
          parent = lChild;
          lChild = 2 * lChild + 1;
      }
      arr[parent] = temp;
  }

运行结果

堆排序算法Java_第15张图片

 

你可能感兴趣的:(算法,排序算法,java,算法)