zoukankan      html  css  js  c++  java
  • 堆排序HeapSort

    学习参考:堆排序 Heap Sort排序六 堆排序


    堆结构:一棵完全二叉树。大根堆:K[ i ] <  K[ 2i ] 、K[ i ] <  K[ 2i+1 ]  。小根堆反之。

    本文测试数据:《严奶奶数据结构》P281

    由于笔者学业繁忙,没有编写使树形结构可视化的代码。各位读者请心中脑补。

    • 堆调整函数:
     1      protected void HeapAdjust(int [] nums,int a,int b){
     2          int i;
     3          for(i=a;a<=b;){
     4              //左子树=根*2+1,右子树=根*2+2
     5              int lPos=a*2+1;
     6              int rPos=(a+1)*2;
     7              //比较找出左右子树最小的一颗
     8              int min=nums[a];//根结点
     9              int nextPos=lPos;//下一个转向的树
    10              boolean isSwaped=false;
    11              if(lPos<=b && nums[lPos]<min){
    12                  nextPos=lPos;
    13                  min=nums[lPos];
    14                  isSwaped=true;
    15              }
    16              if(rPos<=b && nums[rPos]<min){
    17                  nextPos=rPos;
    18                  isSwaped=true;
    19              }
    20              if(!isSwaped) break;
    21              swap(nums,a,nextPos);
    22              a=nextPos;
    23          }
    24      }

    函数描述:这个函数用于【建堆】、【筛选】两个操作。在这个函数中,对数组【a,b】中的元素进行处理,其认为除了“a”,在【a+1,b】中的元素都是满足{堆结构}的定义的。

    1.求出左右子树的下标
    
    2.进行比较,在左右子树存在的情况下,获得值最小的子树(这个值最小的子树,它的值要比根节点的值小)
    
    3.如果没有这样的子树,跳出循环。
    
      有的话,转到子树进行操作,回到 1 进行循环。
    • 建堆
    1         //建堆
    2         for(i=len/2-1;i>=0;i--){
    3             HeapAdjust(nums,i,len-1);
    4         }

    认为最下层的子树是规整(满足堆定义)的。通过从下层往上层调整,建立一棵满足堆定义的小根堆。

    • 筛选
    1         //筛选
    2         int ans[]=new int [len];
    3         for(i=0;i<len;i++){
    4             ans[i]=nums[0];
    5             nums[0]=nums[len-1-i];
    6             HeapAdjust(nums,0,len-2-i);
    7         }

    1.拿出小根堆的根节点(最小),放入输出数组中

    2.把最末尾的节点放入根节点。因为认为现在除了根节点,其他节点都是满足根定义的。所以对根节点使用【堆调整函数】

    3.重复 1,直到拿走堆中所有的节点。


    测试:

    输入:49,38,65,97,76,13,27,49

    输出:13 27 38 49 49 65 76 97 

    完整java代码:

     1 public class Main {
     2 
     3     public static void main(String[] args) {
     4         int []nums={49,38,65,97,76,13,27,49};
     5         HeapSort sort=new HeapSort(nums);
     6         System.out.print(sort);
     7     }
     8 
     9 }
    10     
    11 class HeapSort{
    12     int [] sortAns;
    13     HeapSort(){}
    14     HeapSort(int[] nums){
    15         int i;
    16         int len=nums.length;
    17         //建堆
    18         for(i=len/2-1;i>=0;i--){
    19             HeapAdjust(nums,i,len-1);
    20         }
    21         //筛选
    22         int ans[]=new int [len];
    23         for(i=0;i<len;i++){
    24             ans[i]=nums[0];
    25             nums[0]=nums[len-1-i];
    26             HeapAdjust(nums,0,len-2-i);
    27         }
    28         sortAns=ans;
    29     }
    30     //对[a,b]的元素进行调整。认为除了a都满足堆的条件
    31      protected void HeapAdjust(int [] nums,int a,int b){
    32          int i;
    33          for(i=a;a<=b;){
    34              //左子树=根*2+1,右子树=根*2+2
    35         //     System.out.println("a="+a);
    36              int lPos=a*2+1;
    37              int rPos=(a+1)*2;
    38              //比较找出左右子树最小的一颗
    39              int min=nums[a];//根结点
    40              int nextPos=lPos;//下一个转向的树
    41              boolean isSwaped=false;
    42              if(lPos<=b && nums[lPos]<min){
    43                  nextPos=lPos;
    44                  min=nums[lPos];
    45                  isSwaped=true;
    46              }
    47              if(rPos<=b && nums[rPos]<min){
    48                  nextPos=rPos;
    49                  isSwaped=true;
    50              }
    51              if(!isSwaped) break;
    52              swap(nums,a,nextPos);
    53              a=nextPos;
    54          }
    55      }
    56      void printNums(int[] nums){
    57          int i;
    58          for(i=0;i<nums.length;i++) System.out.print(nums[i]+" ");
    59          System.out.println();
    60      }
    61      private void swap(int []arr,int a,int b){
    62          int tmp=arr[a];
    63          arr[a]=arr[b];
    64          arr[b]=tmp;
    65      }
    66      public String toString(){
    67          int i;
    68          String str=new String("");
    69          for(i=0;i<sortAns.length;i++) str+=String.valueOf(sortAns[i])+" ";
    70          str+="
    ";
    71          return str;
    72      }
    73 }
  • 相关阅读:
    你知道怎么离线安装全局 node 模块吗?
    关于开发视图
    你知道 JavaScript 中的 Arguments 对象都有哪些用途吗?
    前端 JavaScript 实现一个简易计算器
    Docker 系列 _ 01_ 一念缘起
    机器学习资料大全
    pdf、txt文本复制到EXCEL后的格式快速调整法
    习惯的养成
    磁盘剩余空间监控
    please wait while windows configures microsoft visual studio professional 2013
  • 原文地址:https://www.cnblogs.com/TQCAI/p/7640618.html
Copyright © 2011-2022 走看看