一、归并排序
归并排序的时间复杂度为O(nlogn) 这是该算法中最好、最坏和平均的时间性能。
其中比较操作的次数介于(nlogn) / 2和nlogn - n + 1(在每次归并中比较次数不一样)。
赋值操作的次数是(2nlogn)。归并算法的空间复杂度为:0 (n)
归并排序比较占用内存,但却是一种效率高且稳定的算法。
编程中注意,很多人写的函数中都建立了许多局部数组碎片,这增加了内存。使用类成员数组来存储归并后临时数组,才可以真正达到O(n)的空间复杂度。
代码如下:
package Sort;
public class MergeSort {
private int[] b;
public MergeSort(int a[]){
b=new int[a.length];
}
public void mergeS(int a[],int begin,int end){
if(begin<end){
int middle=(begin+end)/2;
mergeS(a,begin,middle);
mergeS(a,middle+1,end);
merge(a,begin,middle,end);
}
}
public void merge(int a[],int begin,int middle,int end){
//third为辅助数组中下标
<span style="white-space:pre"> </span>int third=begin;
int left=begin;
int right=middle+1;
while(left<=middle&&right<=end){
if(a[left]<=a[right]){
b[third++]=a[left++];
}else{
b[third++]=a[right++];
}
}
while(left<=middle){
b[third++]=a[left++];
}
while(right<=end){
b[third++]=a[right++];
}
//将临时数组排好序的数复制回原数组中
while(begin<=end){
a[begin]=b[begin++];
}
}
public static void main(String[] args){
int a[]={10,4,9,7,8,5,11,23,-1,-3,34,3,4,8};
MergeSort ms=new MergeSort(a);
ms.mergeS(a, 0, a.length-1);
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
}
二、希尔排序
希尔排序没啥好说的,是直接插入排序的一种优化,已知序列基本有序,那么直接插入排序时间复杂度可以达到O(n),那么希尔排序就是让序列变得越来越有序,最后一个插入排序将它搞定。时间复杂度是:O(nlogn)~O(n2),平均时间复杂度大致是O(n√n),姑妄听之。
注意:间隔序列中数字互质很重要。
贴代码:
package sort;
public class ShellSort {
//shellsort 间隔序列中数字互质很重要
/**
* @param args
*/
private static final int a[]={45,12,84,1,0,-9,85,123,74,14,16,-23,65,37,73,-1};
private static final int b[]={13,4,1};
public static void shellSort(){
int size=a.length;
for(int i=0;i<3;i++){
//这不就是直接插入排序嘛
<span style="white-space:pre"> </span>for(int j=0;j<b[i];j++){
for(int m=j+b[i];m<size;m+=b[i]){
int n=m-b[i];
int temp=a[m];
while(n>=j&&temp<a[n]){
a[n+b[i]]=a[n];
n-=b[i];
}
a[n+b[i]]=temp;
}
}
}
display();
}
private static void display(){
for(int i=0;i<a.length;i++){
System.out.print(a[i]+", ");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
shellSort();
}
}