zoukankan      html  css  js  c++  java
  • 经典的排序算法java实现版

      1 /**
      2  * 
      3  * @author yuzhiping
      4  * @version 1.0
      5  * 功能说明:计算机领域经典的算法
      6  *
      7  */
      8 public class sortAlgorithm<T extends Comparable<T>> {
      9     
     10     //交换索引i和索引j的值
     11     private void swap(T [] data ,int i,int j){
     12         T tmp;
     13         tmp=data[i];
     14         data[i]=data[j];
     15         data[j]=tmp;
     16     }
     17     
     18     
     19     //-----堆排序 时间复杂度O(nlogn)-----
     20     
     21     public void heapSort(T [] data){
     22         int arrayLength=data.length;
     23         //循环件堆
     24         for(int i=0;i<arrayLength-1;i++){
     25             // 建堆
     26             builMaxdHeap(data, arrayLength - 1 - i);
     27             // 交换堆顶和最后一个元素
     28             swap(data, 0, arrayLength - 1 - i);
     29 
     30         }
     31     }
     32     
     33     // 对data数组从0到lastIndex建大顶堆
     34     private void builMaxdHeap(T[] data, int lastIndex) {
     35         // 从lastIndex处节点(最后一个节点)的父节点开始
     36         for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
     37             // k保存当前正在判断的节点
     38             int k = i;
     39             // 如果当前k节点的子节点存在
     40             while (k * 2 + 1 <= lastIndex) {
     41                 // k节点的左子节点的索引
     42                 int biggerIndex = 2 * k + 1;
     43                 // 如果biggerIndex小于lastIndex,即biggerIndex + 1
     44                 // 代表的k节点的右子节点存在
     45                 if (biggerIndex < lastIndex) {
     46                     // 如果右子节点的值较大
     47                     if (data[biggerIndex].compareTo(data[biggerIndex + 1]) < 0) {
     48                         // biggerIndex总是记录较大子节点的索引
     49                         biggerIndex++;
     50                     }
     51                 }
     52                 // 如果k节点的值小于其较大子节点的值
     53                 if (data[k].compareTo(data[biggerIndex]) < 0) {
     54                     // 交换它们
     55                     swap(data, k, biggerIndex);
     56                     // 将biggerIndex赋给k,开始while循环的下一次循环,
     57                     // 重新保证k节点的值大于其左、右子节点的值。
     58                     k = biggerIndex;
     59                 } else {
     60                     break;
     61                 }
     62             }
     63         }
     64     }
     65      
     66     //-----冒泡排序法 时间复杂度O(n^2)-----
     67     public void bubbleSort(T[] data){
     68         int i,j;
     69         for(i=0;i<data.length-1;i++){
     70             for(j=0;j<data.length-i-1;j++){
     71                 if(data[j].compareTo(data[j+1]) > 0){
     72                     swap(data,j+1,j);
     73                 }
     74             }
     75         }
     76     }
     77      
     78     //-----选择排序法 时间复杂度O(n^2)-----
     79     public void selectSort(T[] data){
     80         int i,j;    
     81          
     82         for(i=0;i<data.length-1;i++){
     83             for(j=i+1;j<data.length;j++){
     84                 if (data[i].compareTo(data[j]) > 0){
     85                     swap(data,i,j);
     86                 }
     87             }
     88         }
     89     }
     90      
     91     //-----快速排序法  时间复杂度为O(log2n)-----
     92     public void quickSort(T[] data){
     93         subQuickSort(data,0,data.length-1);
     94     }
     95      
     96     private void subQuickSort(T[] data,int start,int end){
     97         if( start < end ){
     98             //以第一个元素作为分界值
     99             T base = data[start];
    100             //i从左边开始搜索大于分界值元素的索引
    101             int i = start;
    102             //j从右边开始搜索小于分界值元素的索引
    103             int j = end + 1;
    104             while(true){
    105                 //左边跳过比base小的元素
    106                 while(i < end && data[++i].compareTo(base) <= 0);
    107                 //右边跳过比base大的元素
    108                 while(j > start && data[--j].compareTo(base) >= 0);
    109                  
    110                 if(j > i){
    111                     swap(data,i,j);
    112                 }else{
    113                     break;
    114                 }
    115             }
    116             //将分界值还原
    117             swap(data,start,j);
    118              
    119             //递归左边序列
    120             subQuickSort(data,start,j-1);
    121             //递归右边序列
    122             subQuickSort(data,j+1,end);
    123         }
    124     }
    125      
    126     //-----插入排序法 时间复杂度O(n^2)-----
    127     public void insertSort(T[] data){
    128         int arrayLength = data.length;
    129          
    130         for(int i=1;i<arrayLength;i++){
    131             //当整体后移时保证data[i]的值不会丢失
    132             T tmp = data[i];
    133             //i索引处的值已经比前面所有值都大,表明已经有序,无需插入
    134             //i-1处索引之前的数值已经有序,i-1处索引处元素的值也是最大值
    135             if(data[i].compareTo(data[i-1]) < 0){
    136                 int j = i-1;
    137                 //整体后移一个
    138                 while(j>=0 && data[j].compareTo(tmp) > 0){
    139                     data[j+1] = data[j];
    140                     j--;
    141                 }
    142             data[j+1] = tmp;
    143             }
    144         }
    145     }
    146      
    147     //-----折半插入排序法 时间复杂度-----
    148     public void binaryInsertSort(T[] data) {
    149         int arrayLength = data.length;
    150  
    151         for (int i = 1; i < arrayLength; i++) {
    152             if (data[i - 1].compareTo(data[i]) > 0) {
    153                 // 缓存i处的元素值
    154                 T tmp = data[i];
    155  
    156                 // 记录搜索范围的左边界
    157                 int low = 0;
    158                 // 记录搜索范围的右边界
    159                 int high = i - 1;
    160  
    161                 while (high >= low) {
    162                     // 记录中间位置
    163                     int mid = (high + low) / 2;
    164                     // 比较中间位置数据和i处数据大小,以缩小搜索范围
    165  
    166                     if (tmp.compareTo(data[mid]) > 0) {
    167                         low = mid + 1;
    168                     } else {
    169                         high = mid - 1;
    170                     }
    171                 }
    172                 // 将low~i处数据整体向后移动1位
    173                 for (int j = i; j > low; j--) {
    174                     data[j] = data[j - 1];
    175                 }
    176                 data[low] = tmp;
    177  
    178             }
    179         }
    180     }
    181      
    182     //-----希尔排序法 时间复杂度O(nlogn)O(n^2)具体看h的值-----
    183     public void shellSort(T[] data){
    184         int arrayLength = data.length;
    185         //h保存可变增量
    186          
    187         int h = 1;
    188         while(h<=arrayLength/3){
    189             h = h * 3 + 1;
    190         }
    191          
    192         while(h > 0){
    193             //System.out.println(Arrays.toString( data )+"h="+h);
    194              
    195             for(int i=h;i<arrayLength;i++){
    196                 //当整体后移时,保证data[i]的值不丢失
    197                 T tmp = data[i];
    198                 //i索引处的值已经比前面所有的值大
    199                 //(i-1索引之前的值已经有序的,i-1索引处元素的值就是最大值)
    200                 if(data[i].compareTo(data[i-h]) < 0){
    201                     int j = i-h;
    202                     //整体后移一格
    203                     while(j>=0 && data[j].compareTo(tmp) > 0){
    204                         data[j+h] = data[j];
    205                         j-=h;
    206                     }
    207                      
    208                     //最后将tmp值插入合适的位置
    209                     data[j+h] = tmp;
    210                 }
    211             }
    212             h = (h-1)/3;
    213         }
    214          
    215     }
    216      
    217     //-----归并排序法 时间复杂度为O(nlog2n)-----
    218     public void mergeSort(T[] data){
    219         subMergeSort(data,0,data.length-1);
    220     }
    221      
    222     private void subMergeSort(T[] data,int left,int right){
    223         if(right > left){
    224             //找出中间索引
    225             //System.out.println(  Arrays.toString(data) );
    226             int center = (left + right)/2;
    227             //对左边数组进行递归
    228             subMergeSort(data,left,center);
    229             //对右边数组进行递归
    230             subMergeSort(data,center+1,right);
    231             //合并
    232             merge(data,left,center,right);
    233         }
    234     }
    235      
    236     @SuppressWarnings("unchecked")
    237     private void merge(T[] data, int left, int center, int right) {
    238         Object[] tmpArr = new Object[data.length];
    239         int mid = center + 1;
    240         // third记录中间处索引
    241         int third = left;
    242         int tmp = left;
    243  
    244         while (left <= center && mid <= right) {
    245             // 从两个数组中取出最小的放入中间数组
    246             if (data[left].compareTo(data[mid]) <= 0) {
    247                 tmpArr[third++] = data[left++];
    248             } else {
    249                 tmpArr[third++] = data[mid++];
    250             }
    251         }
    252          
    253         // 剩余部分依次放入中间数组
    254         while (mid <= right) {
    255             tmpArr[third++] = data[mid++];
    256         }
    257         while (left <= center) {
    258             tmpArr[third++] = data[left++];
    259         }
    260          
    261         // 将中间数组的内容复制拷回原数组
    262         // (原left~right范围内德内容被复制回原数组)
    263         while (tmp <= right) {
    264             data[tmp] = (T) tmpArr[tmp++];
    265         }
    266     }
    267      
    268 
    269 
    270     public static void main(String[] args) {
    271         // TODO Auto-generated method stub
    272 
    273     }
    274 
    275 }
  • 相关阅读:
    《剑指Offer》二维数组中的查找
    白话计算机入门书籍--《穿越计算机的迷雾》有感
    Mysql Cluster7.5.6在 windows10 部署安装
    Mysql Cluster7.5.6 windows10 部署安装
    lll
    线程控制
    动态链接库相关知识
    二分查找及其变种简单易懂的模版
    白话 STL next_permutation 原理
    Maven本地上有包还去网上找包
  • 原文地址:https://www.cnblogs.com/doctorJoe/p/4474916.html
Copyright © 2011-2022 走看看