美文网首页ZJ_iOS面试
排序算法之堆排序 Java 实现

排序算法之堆排序 Java 实现

作者: 5d44bc28b93d | 来源:发表于2017-03-11 23:32 被阅读1219次

1.知识补充


1.0 完全二叉树

一棵深度为K,有n个节点的二叉树,对树中节点按照从上至下,从左至右的顺序进行编号,如果编号为i(1<=i<=n)与满二叉树的编号为i的位置一致,则称此树为完全二叉树。


完全二叉树和非完全二叉树示意图.jpg

1.1满二叉树

满二叉树:如果一棵二叉树所有分支都存在左右子节点,且所有的叶子节点都在同一层,则成这棵树为满二叉树。


满二叉树(a)与非满二叉树(b).jpg

1.2 完全二叉树的性质(重点)

如果对具有n个节点二叉树的根节点从0开始编号,则序号为i的节点的双亲结点为(i-1)/2,左孩子的编号为2i+1,右孩子为2i+2。如果从1开始编号,则双亲结点编号为i/2,左孩子结点序号为2i,右孩子结点序号为2i+1.

2 堆(千呼万唤始出来)

堆:n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):
(1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n/2),当然,这是小根堆,大根堆则换成>=号。//k(i)相当于二叉树的非叶子结点,K(2i)则是左子节点,k(2i+1)是右子节点
若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:


树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。

3.堆得建立


算法思路:
1.我们首先将数组进行初始化调整成大根堆。
2.然后进行排序,每次排序时,将最后一个序号n节点的值与根节点0的值进行替换,然后将节点又调整成堆。
3.然后将根节点与n-1进行交换重复步骤2。直到序列为有序

3.1以大根堆为例:

 /**
     * 堆调整算法
     * @param num   数组
     * @param s 调整节序号
     * @param l 数组排序最大的序号 
     */
  public static void HeapAdjust(int[] num,int s,int l){
      int i,j;
      int temp=num[s];
      i=s;
      // 根据二叉树的性质可知道每一个序号对应的子节点以及双亲节点
      for(j=2*i+1;j<=l;j=2*j+1){
          //判断如果j指向数值较大的节点
          if(j<l&&num[j]<num[j+1]){
              j=j+1;
          }
          //如果调整节点大于其子节点最大的值则无需调整
          if(temp>num[j]){
              break;
          }
          //如果小于则将子节点移动到根节点位置,如果还存在子节点则继续判断调整位置的子节点
          //准备继续向下 调整节点
          num[i]=num[j];
          i=j;
      }
      //最后插入数据
      num[i]=temp;
  }                             

3.2堆的建立

   /**
     * 堆建立初始化函数
     * @param nums 数组序列
     * @param l 最大序号
     */
  public static void HeapInit(int[] nums,int l){
      for (int i = (l-1) / 2; i >=0; i--) {
          HeapAdjust(nums, i, l);
      }
  }

3.3 堆的排序算法

  public static void HeapSort(int[] nums,int l){
     for(int i=l;i>0;i--){
         int temp=nums[0];
         nums[0]=nums[i];
         nums[i]=temp;
         //因为每次调整都是对根节点进行调整所以下列方法s永远为0
         HeapAdjust(nums,0,i-1);
     }
  }

3.4最后我们来看看效果

 public static void main(String[] args){
        int[] nums={3,2,4,9,8};
        //第一步根据节点创建堆
        for (int i = (4-1) / 2; i >=0; i--) {
            HeapAdjust(nums, i, 4);
        }
        //第二步排序
        HeapSort(nums,4);
        for(int n:nums){
            System.out.println(n);
        }

    }

输出

2
3
4
8
9

相关文章

  • 排序

    八大排序算法 一、归并排序 递归及非递归的JAVA实现 二、快速排序 快排算法JAVA实现 三、堆排序 堆排序堆排...

  • 排序算法-堆排序

    参考: Java排序算法(五):堆排序 【算法与数据结构】图说堆排序 【数据结构】排序算法:希尔、归并、快速、堆排...

  • 堆排序

    转载:图解排序算法(三)之堆排序 预备知识 堆排序 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选...

  • 排序算法之堆排序 Java 实现

    1.知识补充 1.0 完全二叉树 一棵深度为K,有n个节点的二叉树,对树中节点按照从上至下,从左至右的顺序进行编号...

  • Java实现各种常用的排序算法

    Java实现各种常用的排序算法,包括:冒泡排序、插入排序、二分排序、选择排序、希尔排序、堆排序、快速排序(两种写法...

  • iOS算法总结-堆排序

    iOS算法总结-堆排序 iOS算法总结-堆排序

  • 3.11 堆的概念及堆排序思路

    Chapter3: 更好的查找与排序算法 11. 堆的概念及堆排序 [1] 图解排序算法(三)之堆排序 讲得很好,...

  • 数据结构&算法(一)

    一、Java实现快速排序算法 二、Java实现折半插入排序算法 三、Java实现冒泡排序算法

  • 3.2-选择排序-堆排序

    参考链接 选择排序:堆排序(Heap Sort) 白话经典算法系列之七 堆与堆排序 堆排序与快速排序,归并排序一样...

  • 三大排序算法

    归并排序[稳定的排序算法] 递归实现 非递归实现 快速排序[不稳定的排序算法] 堆排序[不稳定的排序算法]

网友评论

    本文标题:排序算法之堆排序 Java 实现

    本文链接:https://www.haomeiwen.com/subject/fwlvgttx.html