堆排序

来源:互联网 发布:时时彩组三报警软件 编辑:程序博客网 时间:2024/05/17 22:09
    原理:左右节点 大的给父节点,登顶后与相对i最后一个位置的数值进行交换

1、堆排序实现由大到小排序

    public static void swap(int[] data,int i,int j)     {         int temp=data[i];         data[i] =data[j];         data[j]=temp;     }        public static void show(int[] data)     {         for(int num:data)         {             System.out.print(num+"   ");         }          System.out.println("");     }     //12345    6   7     8     //堆排序     public static  void  heapsort  (int[] data)     {         for(int i=0;i<data.length;i++)         {             //循环数组,每次取出最大的 (传数组相对i的最后一个值)             makeheap(data,data.length-1-i);                  swap(data,0,data.length-1-i);//每一次循环的最后把登顶的数换到后面去              }              }                public static  void makeheap(int[] data,int lastindex) //一次循环 lastindex一直为13 i为6--0      {          //n   2n   2n+1   堆从1开始          for(int i=(lastindex-1)/2;i>=0;i--)//从父亲节点循环下去 父节点 在第一次结果出来(一次登顶)之前,遍历了所有的父节点  6 5 4 3 2 1 0          {              int  nowkey=i;//记录当前判断的节点  父节点 在第一次结果出来(一次登顶)之前,遍历了所有的父节点  6 5 4 3 2 1 0              while(2*nowkey+1 <=lastindex)//小于最终节点循环下去   当前节点小于最终节点循环下去  不越界继续循环              {                                    int bigindex=2*nowkey+1;//记录当前节点// 一次登顶之前 13 11 9 7 5 11 3 9 1 5 13                  if( bigindex<lastindex)                  {                      if(data[bigindex]<data[bigindex+1])                    {                          bigindex++;//取出左右节点的最大,为了下边 让最大的子节点与父节点进行交换进行                      }                  }                      if(data[nowkey] <data[bigindex])//对比父节点与孩子节点最大值,大的值放在父节点                  {                      swap(data,nowkey,bigindex);//交换                      nowkey=bigindex;//取得最大值,记录                  }                                    else                  {                      break;                  }                              }               }      }          public static void main(String[] args)      {                 int []data =new int[]{5,1,6,17,118,9,112,0,23,18,15,189,23,13};         System.out.println("排序前:");         show(data);          heapsort(data);          System.out.println("排序后:");         show(data);     }  


结果输出:

排序前:5   1   6   17   118   9   112   0   23   18   15   189   23   13   排序后:0   1   5   6   9   13   15   17   18   23   23   112   118   189   

2、实现从大到小的排序,只需要把标识为红色代码大于符号修改为小于即可。

3、取最大的5个数:只排序最大的5个数,别的不再进行排序

    public static void swap(int[] data,int i,int j)      {          int temp=data[i];          data[i] =data[j];          data[j]=temp;      }         public static void show(int[] data)      {          for(int num:data)          {              System.out.print(num+"   ");          }           System.out.println("");      }      //12345    6   7     8      //堆排序      public static  void  heapsort  (int[] data)      {      for(int i=0;i<5;i++)        {              //循环数组,每次取出最大的 (传数组相对i的最后一个值)              makeheap(data,data.length-1-i);;              swap(data,0,data.length-1-i);//每一次循环的最后把登顶的数换到后面去          }      }              //      makeheap(data,data.length-1-i);       public static  void makeheap(int[] data,int lastindex) //一次循环 lastindex一直为13 i为6--0       {           for(int i=(lastindex-1)/2;i>=0;i--)//从父亲节点循环下去 父节点 在第一次结果出来(一次登顶)之前,遍历了所有的父节点  6 5 4 3 2 1 0           {               int  nowkey=i;//记录当前判断的节点  父节点 在第一次结果出来(一次登顶)之前,遍历了所有的父节点  6 5 4 3 2 1 0               while(2*nowkey+1 <=lastindex)//小于最终节点循环下去   当前节点小于最终节点循环下去  不越界继续循环               {                                      int bigindex=2*nowkey+1;//记录当前节点// 一次登顶之前 13 11 9 7 5 11 3 9 1 5 13  //                  System.out.println(nowkey);// 65432514026                   if( bigindex<lastindex)                   {                       if(data[bigindex]<data[bigindex+1])                       {                           bigindex++;//取出左右节点的最大,为了下边 让最大的子节点与父节点进行交换进行                       }                   }                   if(data[nowkey] <data[bigindex])//对比父节点与孩子节点最大值,大的值放在父节点                   {                       swap(data,nowkey,bigindex);//交换                       nowkey=bigindex;//取得最大值,记录                   }                                      else                   {                       break;                   }                               }                                         }       }      public static void main(String[] args)       {                   int []data =new int[]{5,1,6,17,118,9,112,0,23,18,15,189,23,13};           heapsort(data);           //由小到大排序 取最大的前5个数           System.out.print("最大的5个数为:");          for(int i=data.length-1;i>=data.length-1-4;i--)               {                   System.out.print("  "+data[i]);               }           System.out.println();             System.out.println("当前的数组为:");             show(data);      } 

结果输出:

最大的5个数为:  189  118  112  23  23当前的数组为:1   18   13   17   15   9   6   0   5   23   23   112   118   189   
4、取最小的5个数同理可证。

0 0