堆排序算法Java

基本原理

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

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

3):重复步骤2

 小知识点

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

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

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

步骤

第一步:构建大顶堆

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

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

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

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

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

 

 大顶堆完成

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

 

 

 

 重复

 

 重复

 

 重复

 

 重复得出结果

 

 

代码

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;
  }

运行结果

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值