排序之插入、归并、快速排序

来源:互联网 发布:ubuntu登录界面循环 编辑:程序博客网 时间:2024/06/05 20:54

一、插入排序

最简单的排序方法,类似玩扑克,开始时我们的左手为空,之后我们每次从桌子上拿走一张牌并插入左手中的正确位置。
我们可以将牌分为三部分,左手中的已排序好的牌,右手中的一张牌,桌子上的一堆牌。而为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较,保证左手中的牌总是排序好的。

public void insertionSort(int a[]){    for(int i=1;i<a.length;i++){        int key=a[i];        int j=i-1;        while(j>=0&&a[j]>key){            a[j+1]=a[j];            j--;        }        a[j+1]=key;    }}

算法很简单,但是算法时间复杂度为O(n²),除非数组已经完全排序好,这时的时间复杂度为O(n)。

二、归并排序

同样假定有两堆牌面朝上的牌,每堆都已排序,最小的牌在顶上,我们希望把这两堆牌合并成一堆排序好的牌。我们只要不断的从两堆牌的顶上选取较小的那一张,直到一堆为空就好。
就如a[p..q]和a[q+1…r]各自都按照升序排列,我们需要重新安排数组a中的位置使a[p,r]按照升序排列,可以采用同样的办法。

public void merge(int a[],int p,int q,int r){    int[] temp=new int[r-p+1];    int i=p;    int j=q+1;    int k=0;    while(i<=q&&j<=r){        if(a[i]<a[j]){            temp[k]=a[i];            i++;        }else{            temp[k]=a[j];            j++;        }        k++;    }    if(i>q){        while(j<=r){            temp[k++]=a[j++];        }    }else{        while(i<=q){            temp[k++]=a[i++];        }    }    int x=p;    for(int l=0;l<r-p+1;l++){        a[x++]=temp[l];    }}

接下来我们采用自顶向下的方法就好:

public void mergeSort(int a[],int p,int r){    if(p<r){        int mid=(p+r)/2;        mergeSort(a, p, mid);        mergeSort(a, mid+1, r);        merge(a, p, mid, r);    }}

归并排序的时间复杂度为O(nlgn),明显优于插入排序。

三、快速排序

将数组a[p..r]分为两部分,左半部分a[p..q-1]都小于等于a[q],右半部分a[q+1…r]都大于a[q]。
方法就是通过将数组a[p..r-1]的所有元素都与a[r]进行比较,只要比a[r]小的都扔到左边,找到一个扔一个。

public int partition(int a[],int p,int r){    int i=p-1;    int j=p;    while(j<r){        if(a[j]<a[r]){            i++;            int temp=a[j];            a[j]=a[i];            a[i]=temp;        }        j++;    }    int temp=a[i+1];    a[i+1]=a[r];    a[r]=temp;    return i+1; }

然后我们通过递归调用快速排序,对a[p,q-1],a[q+1,r]进行排序:

public void quickSort(int a[],int p,int r){    if(p<r){        int q=partition(a,p,r);        quickSort(a,p,q-1);        quickSort(a,q+1,r);    }}

快速排序的时间复杂度同样为O(nlgn),但是存在最坏情况,就是在已排序好的数组时,划分时左右两部分会分别包括0个元素和n-1个元素,这种情况下,时间复杂度为O(n²)。

阅读全文
0 0