排序算法思想

选择排序:

从数据中选择最小的一个并排在第一个位置,接下来从余下的数据中选择最小的排在第二个位置,依次类推。。

算法需要N2/2次比较和N次交换

特点:

1)程序运行时间与输入无关:每一次排序都不能为下一次排序提供有用的信息。有序的数组和无序的数组排序所用的时间一样长。

2)数据移动是最少的:两两交换只需交换N次,是所有算法中交换次数最少的

package sort;

public class ChooseSort {

    public static int[] sort(int[] a){
        
        for(int i=0;i<a.length;i++)
        {
            int min=a[i];
            int minIndex=i;
            for(int j=i+1;j<a.length;j++)
            {
                if(a[j]<min)
                {
                min=a[j];
                minIndex=j;
                }
            }
            int temp=a[i];
            a[i]=min;
            a[minIndex]=temp;
        }
        return a;
    }
    
    public static void main(String args[]){
        int a[]={5,3,2,1,4};
        int []b=sort(a);
        for(int i=0;i<b.length;i++)
            System.out.println(b[i]);
    }
}

 

 

插入排序:

   认为左边部分为有序的,每一次都将右边第一个元素放在左边那部分的适当位置,使得左边部分始终有序。而右边第一个元素也就是要插入的元素的位置腾出来之后,左边的所有比要插入元素大的数据会一次向又移。

   平均需要进行N2/4次比较和N2/4次交换,最差的情况需要进行N2/2次比较和N2/2次交换

   特点:

   当数组本身就是一个有序数组时则不需要移动。

   插入排序对于部分有序数组很有效,部分有序数组包括这种情况:数组中每个元素距离他的最终位置都不远

 1 package sort;
 2 
 3 public class InsertSort {
 4 
 5     public static int[] sort(int []a){
 6         for(int i=1;i<a.length;i++)
 7         {
 8             int current=a[i];
 9             for(int j=i;j>0;j--)
10             {
11                 if(a[j]<a[j-1])
12                 {
13                     int temp=a[j];
14                     a[j]=a[j-1];
15                     a[j-1]=temp;
16                 }
17             }
18         }
19         return a;
20     }
21     
22     
23     public static void main(String args[]){
24         int a[]={3,2,1,4,9,5};
25         a=sort(a);
26         for(int i=0;i<a.length;i++)
27             System.out.println(a[i]);
28     }
29 }

 希尔排序:

希尔排序是改进后的插入排序,首先定义一个间隔d,将数组数据进行分组,用插入排序法保证每个分组内是有序的,之后缩减间隔d的值,重新分组排序,直到间隔为1时,即可保证整个数组是有序的。希尔排序充分利用了插入排序的特性,使得部分有序数组的排序性能大幅度提高。

特性:希尔排序适用于大数组,效果明显。但对于间隔d的选择却是一个问题

 1 package sort;
 2 
 3 public class ShellSort {
 4 
 5     public static int[] sort(int []a){
 6         int d=a.length/3;
 7         while(d>0){
 8             for(int i=d;i<a.length;i++)
 9             {
10                 for(int j=i;j>0;j=j-d)
11                 {
12                 if(a[j]<a[j-d])
13                 {
14                     int temp=a[j];
15                     a[j]=a[j-d];
16                     a[j-d]=temp;
17                     
18                 }
19                 }
20             }
21             d--;
22         }
23         return a;
24     }
25     public static void main(String args[]){
26         int a[]={5,3,1,4,2};
27         a=sort(a);
28         for(int i=0;i<a.length;i++)
29             System.out.println(a[i]);
30     }
31 }

 归并排序:

归并排序分为自顶向下和自底向上两种方法,自顶向下采用的是递归的方法,自底向上则是这样的:首先一个一个元素归并,之后两两归并,接着四四归并。但是归并时第二组的元素个数可能会和第一组不同。

自底向上方法:

 1 package sort;
 2 
 3 public class BottomToTopMergeSort {
 4 
 5     /**
 6      * @param args
 7      */
 8     public static void main(String[] args) {
 9         // TODO Auto-generated method stub
10       int a[]={5,3,2,1,4};
11       sort(a);
12       for(int i=0;i<a.length;i++)
13           System.out.println(a[i]);
14     }
15     
16     public static void merge(int[]a,int lo,int mid,int hi){
17         int []aux=new int[a.length];
18         for(int i=lo;i<=hi;i++)
19             aux[i]=a[i];
20         int i=lo;
21         int j=mid+1;
22         for(int k=lo;k<=hi;k++)
23         {
24             if(i>mid) a[k]=aux[j++];
25             else if(j>hi) a[k]=aux[i++];
26             else if(aux[i]>aux[j]) a[k]=aux[j++];
27             else a[k]=aux[i++];
28         }
29     }
30     public static void sort(int []a){
31         int len=a.length;
32         for(int size=1;size<len;size=size+size)
33         {
34             for(int lo=0;lo<len-size;lo+=size+size){
35                 merge(a,lo,lo+size-1,Math.min(lo+size+size-1, len-1));
36             }
37         }
38     }
39     
40 }

在该方法中,有两个for循环,第一个for循环用来确定归并元素的个数,第一轮是一个一个归并,第二轮是两两归并,第三轮是四四归并。第二个for循环用来进行分组归并,

for(int lo=0;lo<len-size;lo+=size+size)

从标号为0的元素开始,到长度减去归并组中元素个数,每次跨越两个组。

merge(a,lo,lo+size-1,Math.min(lo+size+size-1, len-1));

还有一点需要注意的是,因为最后无法确定还余多少个元素,因此应取长度或者正规个数最小的那个

 

自顶向下递归排序:

 1 package sort;
 2 
 3 public class BottomToTopMergeSort {
 4 
 5     /**
 6      * @param args
 7      */
 8     public static void main(String[] args) {
 9         // TODO Auto-generated method stub
10       int a[]={5,3,2,1,4};
11       sort(a);
12       for(int i=0;i<a.length;i++)
13           System.out.println(a[i]);
14     }
15     
16     public static void merge(int[]a,int lo,int mid,int hi){
17         int []aux=new int[a.length];
18         for(int i=lo;i<=hi;i++)
19             aux[i]=a[i];
20         int i=lo;
21         int j=mid+1;
22         for(int k=lo;k<=hi;k++)
23         {
24             if(i>mid) a[k]=aux[j++];
25             else if(j>hi) a[k]=aux[i++];
26             else if(aux[i]>aux[j]) a[k]=aux[j++];
27             else a[k]=aux[i++];
28         }
29     }
30     public static void sort(int []a){
31         int len=a.length;
32         for(int size=1;size<len;size=size+size)
33         {
34             for(int lo=0;lo<len-size;lo+=size+size){
35                 merge(a,lo,lo+size-1,Math.min(lo+size+size-1, len-1));
36             }
37         }
38     }
39     
40 }

 

posted on 2014-09-28 11:49  Chris兔的小佳佳  阅读(138)  评论(0)    收藏  举报