各种排序算法(4)


  1. package nuaa.ds;  
  2.   
  3. public class Sort<T>{  
  4.     //插入排序  
  5.     public void insertionSort(T[] t,Comparator<T> c){  
  6.         for(int i=1;i<t.length;i++){//确定有序序列  
  7.             T temp = t[i];//空出位置  
  8.             for(int j=i-1;j>=0;j--){//往前依次查找  
  9.                 if(c.compare(temp, t[j])<0){  
  10.                     t[j+1] = t[j];//前面的值大就往后移一位  
  11.                 }else{  
  12.                     t[j+1] = temp;//前面的值等于或者小于就插入  
  13.                     break;  
  14.                 }  
  15.                 if(j==0){//循环到头了  
  16.                     t[0] = temp;  
  17.                 }  
  18.                   
  19.             }  
  20.         }  
  21.     }  
  22.       
  23.     //希尔排序:思路类似插入排序  
  24.     public void shellSort(T[] t,Comparator<T> c){  
  25.         //除以2.2分割貌似是最佳的,最后分割必须为1  
  26.         for(int gap=t.length/2;gap>0;gap=(gap==21:(int)(gap/2.2))){//加了个分割循环  
  27.             for(int i=gap;i<t.length;i+=gap){  
  28.                 T temp = t[i];//当前的为坑  
  29.                 for(int j=i-gap;j>=0;j-=gap){//0到i每个都比较,大的往后坑里填,小的就填值  
  30.                     if(c.compare(t[j], temp)>0){  
  31.                         t[j+gap]=t[j];  
  32.                     }else{  
  33.                         t[j+gap]=temp;  
  34.                         break;  
  35.                     }  
  36.                     if(j==0){//循环到头了  
  37.                         t[0] = temp;  
  38.                     }  
  39.                 }  
  40.             }  
  41.         }  
  42.     }  
  43.       
  44.     //冒泡排序  
  45.     public void bubbleSort(T[] t,Comparator<T> c){  
  46.         for(int i=0;i<t.length;i++){//有length-1个元素要移动  
  47.             for(int j=0;j<t.length-i-1;j++){//从开始位置往后扫描  
  48.                 if(c.compare(t[j], t[j+1])>0){//如果发现前面元素比后面大  
  49.                     T temp=t[j];t[j]=t[j+1];t[j+1]=temp;//就互换  
  50.                 }  
  51.             }  
  52.         }  
  53.     }  
  54.       
  55.     //选择排序  
  56.     public void selectionSort(T[] t,Comparator<T> c){  
  57.         for(int i=0;i<t.length;i++){//确定位置当成最小值存放点  
  58.             int k=i;  
  59.             for(int j=i+1;j<t.length;j++){//从开始位置往后扫描  
  60.                 if(c.compare(t[k], t[j])>0){//发现小值就记录下标  
  61.                     k = j;  
  62.                 }  
  63.             }  
  64.             T temp=t[i];t[i]=t[k];t[k]=temp;//存放入最小值  
  65.         }  
  66.     }  
  67.       
  68.     //归并排序  
  69.     public void mergeSort(T[] t,Comparator<T> c){  
  70.         mergeSort(t,0,t.length-1,c);  
  71.     }  
  72.       
  73.     private void mergeSort(T[] t,int low,int high,Comparator<T> c){  
  74.         if(low<high){//分割到一为止,  
  75.             int middle = (low+high)/2;  
  76.             mergeSort(t,low,middle,c);  
  77.             mergeSort(t,middle+1,high,c);  
  78.             //单个元素不需要排序,因此排序过程也在if语句里面  
  79.             T[] temp = (T[])new Object[high-low+1];  
  80.             int a = 0;//temp 的下标  
  81.             int lowIndex = low;//low到middle的索引,  
  82.             int highStart = middle+1;  
  83.               
  84.             while((lowIndex<=middle)&&(high>=highStart)){//排序好的分割2列都有值  
  85.                   
  86.                 if(c.compare(t[lowIndex], t[highStart])<=0){  
  87.                     temp[a++] = t[lowIndex];  
  88.                     lowIndex++;  
  89.                 }else{  
  90.                     temp[a++] = t[highStart];  
  91.                     highStart++;  
  92.                 }  
  93.             }  
  94.             while(lowIndex<=middle){//索引低的部分还有剩余项  
  95.                 temp[a++] = t[lowIndex];  
  96.                 lowIndex++;  
  97.             }  
  98.             while(high>=highStart){//索引高的部分还有剩余项  
  99.                 temp[a++] = t[highStart];  
  100.                 highStart++;  
  101.             }  
  102.             //重置temp的索引并拷贝回原数组  
  103.             for(a=0;a<temp.length;a++){  
  104.                 t[low++] = temp[a];  
  105.                   
  106.             }  
  107.               
  108.               
  109.         }  
  110.           
  111.           
  112.     }  
  113.     //快速排序  
  114.     public void quickSort(T[] t,Comparator<T> c){  
  115.         quickSort(t,0,t.length-1,c);  
  116.     }  
  117.       
  118.     private void quickSort(T[] t,int low,int high,Comparator<T> c){  
  119.         /*if(high-low==1){//分割到2个数快速排序有问题 
  120.             this.bubbleSort(t, c); 
  121.             return; 
  122.             if(c.compare(t[low], t[high])>0){ 
  123.                 T temp=t[low];t[low]=t[high];t[high]=temp; 
  124.             } 
  125.              
  126.             return; 
  127.              
  128.         }*/  
  129.         if(low<high){//一个数则不用排序  
  130.             int middle = (low+high)/2;  
  131.             T temp;//交换值的临时变量  
  132.             //三个if确定分割点并将分割点放在最后  
  133.             if(c.compare(t[low], t[middle])>0){  
  134.                 temp = t[low];t[low] = t[middle];t[middle] = temp;   
  135.             }  
  136.             if(c.compare(t[low], t[high])>0){  
  137.                 temp = t[low];t[low] = t[high];t[high] = temp;  
  138.             }  
  139.             if(c.compare(t[middle], t[high])<0){  
  140.                 temp = t[middle];t[middle] = t[high];t[high] = temp;  
  141.             }  
  142.             int lowIndex = low;  
  143.             int highIndex = high;  
  144.             /** 
  145.              * 循环内只能放小于大于不能放等于,这样2个下标移动的时候才肯定会 
  146.              * 在最小和最大处停下来,而带来的副产品是下标的自增自减一定要放 
  147.              * 在循环内,不然会造成循环。 
  148.              */  
  149.             while(true){//等也要停下来防止越界  
  150.                 while(c.compare(t[++lowIndex], t[high])<0)//lowIndex先开始因此  
  151.                                                     //循环break后互换用lowIndex  
  152.                     ;  
  153.                 while(c.compare(t[--highIndex], t[high])>0)//自增自减放下面是死循环  
  154.                     ;                                      //加等号相等依然执行会越界  
  155.                 if(lowIndex>=highIndex)  
  156.                     break;  
  157.                 temp=t[lowIndex];t[lowIndex]=t[highIndex];t[highIndex]=temp;  
  158.             }  
  159.             temp=t[lowIndex];t[lowIndex]=t[high];t[high]=temp;  
  160.               
  161.               
  162.             quickSort(t,low,lowIndex-1,c);  
  163.           
  164.             quickSort(t,lowIndex+1,high,c);  
  165.         }  
  166.           
  167.     }  
  168.       
  169.     //堆排序  
  170.       
  171.     public void heapSort(T[] t,Comparator<T> c){  
  172.         createHeap(t,t.length-1,c);//建立初堆  
  173.         for(int i=t.length-1;i>0;i--){     //每次最后和第一个元素互换,将最大元素  
  174.             T temp=t[i];t[i]=t[0];t[0]=temp; //沉底,第一个不需要所以for条件为>0  
  175.             reconstruct(t,0,i-1,c); //数组从0~i-1重新构造堆  
  176.         }  
  177.     }  
  178.       
  179.     /** 
  180.      * 数组下标从0开始,二叉树从1开始,注意转换 
  181.      * @param t 
  182.      * @param lastIndex 数组的最后一个索引下标 
  183.      * @param c 
  184.      */  
  185.     private void createHeap(T[] t,int lastIndex,Comparator<T> c){  
  186.         for(int i=(lastIndex+1)/2;i>=1;i--)//i的值为二叉树的根下标,依次调整为堆  
  187.             reconstruct(t,i-1,t.length-1,c);//传递的为数组下标  
  188.     }  
  189.     /** 
  190.      *  
  191.      * @param t 
  192.      * @param firstIndex  数组第一个下标 
  193.      * @param lastIndex   数组最后一个下标 
  194.      * @param c 
  195.      */  
  196.     private void reconstruct(T[] t,int firstIndex,int lastIndex,Comparator<T> c){  
  197.         int first = firstIndex+1;//转化为二叉树  
  198.         int last = lastIndex+1;//         的下标  
  199.         int index = first*2;  
  200.         while(index<=last){//左子树存在  
  201.             if(index+1<=last&&c.compare(t[index], t[index-1])>0){//右子树存在且大  
  202.                 if(c.compare(t[first-1],t[index])<0){//右子树大于根  
  203.                     T temp=t[first-1];t[first-1]=t[index];t[index]=temp;  
  204.                     first = index+1;  
  205.                     index = 2*first;  
  206.                 }else{  
  207.                     break;  
  208.                 }  
  209.             }else if(c.compare(t[first-1], t[index-1])<0){  
  210.                 T temp=t[first-1];t[first-1]=t[index-1];t[index-1]=temp;  
  211.                 first = index;  
  212.                 index = first*2;  
  213.             }else{  
  214.                 break;  
  215.             }  
  216.         }  
  217.     }  
  218.       
  219. }  

一些盲点:归并排序究竟在外部排序怎么用?外部排序哪些算法?


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值