您的位置:首页 > 编程语言

排序算法,插入、快速、希尔、基数、归并排序的代码实现和效率分析

2014-09-30 15:31 531 查看
排序算法,插入、快速、希尔、基数、归并排序

效率分析

代码实现

package puretest;

import java.util.ArrayList;
import java.util.List;

public class paixu {  
 /**
  * 归并排序,稳定的排序。
  * 将序列分为2个子序列,对子序列排序(迭代)
  * 再将已经排序好的子序列合并
  * 最差时间复杂度(nlog n),最优时间复杂度(n)
  * 平均时间复杂度(nlog n)最差空间复杂度(n)
  * @param nums
  * @param low
  * @param high
  * @return
  */
 public  Comparable[] mergesort(Comparable[] nums, int low, int high) {  
        int mid = (low + high) / 2;  
        if (low < high) {  
            // 左边  
         mergesort(nums, low, mid);  
            // 右边  
         mergesort(nums, mid + 1, high);  
            // 左右归并  
            merge(nums, low, mid, high);  
        }  
        return nums;  
    }  
  
    public  void merge(Comparable[] nums, int low, int mid, int high) {  
     Comparable[] temp = new Comparable[high - low + 1];  
        int i = low;// 左指针  
        int j = mid + 1;// 右指针  
        int k = 0;  
  
        // 把较小的数先移到新数组中  
        while (i <= mid && j <= high) {  
            if (nums[i].compareTo( nums[j])>0) {  
                temp[k++] = nums[i++];  
            } else {  
                temp[k++] = nums[j++];  
            }  
        }  
  
        // 把左边剩余的数移入数组  
        while (i <= mid) {  
            temp[k++] = nums[i++];  
        }  
  
        // 把右边边剩余的数移入数组  
        while (j <= high) {  
            temp[k++] = nums[j++];  
        }  
  
        // 把新数组中的数覆盖nums数组  
        for (int k2 = 0; k2 < temp.length; k2++) {  
            nums[k2 + low] = temp[k2];  
        }  
    }  

   /**
    * 快速排序,将序列按某个值分为两个子序列,第一个序列都小于该值,第二个序列则大于该值
    * 然后再对子序列进行迭代。
    * 最差时间复杂度(n^2),最优(nlogn),平均(nlogn)
    * @param data
    * @param min
    * @param max
    */
    public  void QuickSort(Comparable []data,int min ,int max){  

            if(min<max){  
             int mid = getmid(data,min,max);
             QuickSort(data,min,mid-1);
             QuickSort(data,mid+1,max);
            }  
        }     
    private  int getmid(Comparable[] data, int min, int max) {
 <span style="white-space:pre">		</span> /**
 <span style="white-space:pre">		</span> * <p>Title: getmid</p>
 <span style="white-space:pre">		</span> * <p>Description: </p>
 <span style="white-space:pre">		</span> */ 
     Comparable temp=data[min];
     
     while(min<max)
     {
     <span style="white-space:pre">		</span> if(min<max&&data[max].compareTo(temp)>0)
     <span style="white-space:pre">			</span> max--;
     <span style="white-space:pre">		</span> data[min]=data[max];
     <span style="white-space:pre">		</span> if(min<max&&data[max].compareTo(temp)<0)
     <span style="white-space:pre">			</span> min++;
     <span style="white-space:pre">		</span> data[max]=data[min];
     }
     data[min]=temp;
     return min;
 } 
    
    /**
     * 插入排序
     * 构建有序序列,对于未排序数据,
     * 在已排序序列中从后向前扫描,找到相应位置并插入。
     * 最差时间复杂度 O(n^2),最优时间复杂度 O(n),平均时间复杂度O(n^2)
     * @param data
     */
    public  void insertionSort(Comparable []data){ //插入排序 1
        for(int index=1;index<data.length;index++){  
            Comparable key = data[index];  
            int position = index;  
            //shift larger values to the right  
            while(position>0&&data[position-1].compareTo(key)>0){  
                data[position] = data[position-1];  
                position--;  
            }  
            data[position]=key;  
        }     
    } 
    /**
     * 插入排序
     * @param c1
     * @return
     */
    public  Comparable[] insertSort(Comparable[] c1) {  //插入排序2
        for(int i=1; i<c1.length; i++) {  
            for(int j=i; j>0; j--) {  
                if(c1[j].compareTo(c1[j-1])>0) {  
                    Comparable temp = c1[j];  
                    c1[j] = c1[j-1];  
                    c1[j-1] = temp;  
                } else {  
                    break;  
                }  
            }  
        }  
        return c1;  
    }  
/**
 * 希尔排序,对插入排序的变形,非稳定排序算法,
 * 根据步长d来讲序列分为d个子序列,再对子序列排序
 * 然后再将d缩小,再次排序...
 * 已知的最好步长串行是由Sedgewick提出的 (1, 5, 19, 41, 109,...),本文采用1+3*n
 * @param c3
 */
    
 public  void ShellSort(Comparable[] c3) {
 <span style="white-space:pre">		</span> /**
 <span style="white-space:pre">		</span> * <p>Title: ShellSort</p>
 <span style="white-space:pre">		</span> * <p>Description: </p>
 <span style="white-space:pre">		</span> */ 
 <span style="white-space:pre">		</span> int d = 1;
 <span style="white-space:pre">		</span> while(d<c3.length/3)
 <span style="white-space:pre">		</span> {
 <span style="white-space:pre">			</span> d=d*3+1;
 <span style="white-space:pre">		</span> }
 <span style="white-space:pre">		</span> //d=d/3;
 <span style="white-space:pre">		</span> for(;d>=1;d=d/3)
 <span style="white-space:pre">		</span> {
 <span style="white-space:pre">			</span> for(int k=0;k<d;k++)
 <span style="white-space:pre">			</span> {
 <span style="white-space:pre">				</span> for(int i = d+k;i<c3.length;i=i+d)
 <span style="white-space:pre">				</span> {

 <span style="white-space:pre">					</span> for (int j = i; j >= d && c3[j].compareTo(c3[j-d]) < 0; j-=d) {
 <span style="white-space:pre">		</span>                    Comparable temp = c3[j];
 <span style="white-space:pre">		</span>                    c3[j]=c3[j-d];
 <span style="white-space:pre">		</span>                    c3[j-d]=temp;
 <span style="white-space:pre">		</span>                 }
 <span style="white-space:pre">				</span> }
 <span style="white-space:pre">			</span> }
 <span style="white-space:pre">		</span> }
 <span style="white-space:pre">			</span> 
 }
/**
 * 基数排序,将数值按照位数进行排序,依次对最高位,次高位...排序,最差时间复杂度O(kN),k为最大值位数
 * @param a
 */
 public  void radixSort(int[] a){  
 <span style="white-space:pre">		</span> radixsort(a);  
    
 }  
 public static  void radixsort(int[] array){     
                  
             //首先确定排序的趟数;     
         int max=array[0];     
         for(int i=1;i<array.length;i++){     
                if(array[i]>max){     
                max=array[i];     
                }     
             }     
  
     int time=0;     
            //判断位数;     
             while(max>0){     
                max/=10;     
                 time++;     
             }     
                  
         //建立10个队列;     
             List<ArrayList> queue=new ArrayList<ArrayList>();     
             for(int i=0;i<10;i++){     
                 ArrayList<Integer> queue1=new ArrayList<Integer>();   
                 queue.add(queue1);     
         }     
                 
             //进行time次分配和收集;     
             for(int i=0;i<time;i++){     
                      
                 //分配数组元素;     
                for(int j=0;j<array.length;j++){     
                     //得到数字的第time+1位数;   
                    int x=array[j]%(int)Math.pow(10, i+1)/(int)Math.pow(10, i);  
                    ArrayList<Integer> queue2=queue.get(x);  
                    queue2.add(array[j]);  
                    queue.set(x, queue2);  
             }     
                 int count=0;//元素计数器;     
             //收集队列元素;     
                 for(int k=0;k<10;k++){   
                 while(queue.get(k).size()>0){  
                     ArrayList<Integer> queue3=queue.get(k);  
                         array[count]=queue3.get(0);     
                         queue3.remove(0);  
                     count++;  
               }     
             }     
           }     
                  
    }    
 public static void datemin(int longs,int max)
 {
 <span style="white-space:pre">		</span> paixu pai = new paixu();
 <span style="white-space:pre">		</span> Comparable []c1=new Comparable[longs];  
        Comparable []c2=new Comparable[longs]; 
        Comparable []c3=new Comparable[longs]; 
        Comparable []c4=new Comparable[longs]; 
        int[] a = new int[longs];
        for(int i = 0;i<c1.length;i++)
        {
         Comparable key =Math.random()*max;
         c1[i]=key;
         c2[i]=key;
         c3[i]=key;
         c4[i]=key;
         a[i]=  (int) (Math.random()*max);
        }
        
     long Mili0=System.currentTimeMillis();// 当前时间对应的毫秒数
     System.out.println("基数排序");  
     //radixSort(a);
     long Mili1=System.currentTimeMillis();// 当前时间对应的毫秒数
     System.out.println("结束 s"+(Mili1-Mili0));

     System.out.println("归并排序"); 
     pai.mergesort(c1,0,c1.length-1);
        long Mili2=System.currentTimeMillis();
     System.out.println("结束 s"+(Mili2-Mili1));
        
        System.out.println("快速排序");
        pai.QuickSort(c2,0,c2.length-1);
        long Mili3=System.currentTimeMillis();
     System.out.println("结束 s"+(Mili3-Mili2));
     
     System.out.println("希尔排序");
     pai.ShellSort(c3);
        long Mili4=System.currentTimeMillis();
     System.out.println("结束 s"+(Mili4-Mili3));
 }
 
    public static void main(String []args){
     int longs=1000000;
     int max=10000;
     datemin( longs, max);
    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐