1. 程式人生 > >幾個內部排序演算法的總結(JAVA版)

幾個內部排序演算法的總結(JAVA版)

插入排序

1、直接插入排序

public void insertSort(int[] a){
 for(int i=0;i<a.length;i++){
  int key=a[i];
  int pos=i;
  while(pos>0&&a[pos-1]>key){
   a[pos]=a[pos-1];
   pos--;
  }
  a[pos]=key; 
 }
 for(int i=0;i<a.lenght;i++){
  System.out.print(a[i]+" ");
 }
}

直接插入排序(Straight Insertion Sort)是一種最簡單的排序方法:將一個記錄插入到已排好的有序表中,從而得到一個新的、記錄數增1 的有序表。

時間複雜度O(n2),空間複雜度O(1),穩定。

2、希爾排序

public void shellSort(int[] a){
 double=d1.length;
 int temp=0;
 while(true){
  d1=Math.ceil(d1/2);
  int l=(int)d1;
  for(int i=0;i<l;i++){
   for(int j=i+l;j<a.length;j++){
    int n=j-l;
    temp=a[j];
    for(;n>=0&&temp<a[n];n-=1)
     a[n+l]=a[n];
    a[n+1]=temp;
   }
  }
  if(l==1)
   break;
 }//while
}
希爾排序(Shell‘s Sort)又稱為“最小增量排序”:先將整個帶排記錄分割成為若干子序列分別進行直接插入排序,待整個序列中的記錄“基本有序”時,再將全體記錄進行一次直接插入排序。詳細說明:先將要排序的一組數按增量d(d=n/2,n為待排個數)分成若干組,對每組中全部元素進行直接插入排序,然後按d/2增量分組,直至d=1結束。

時間複雜度O(n2),不穩定。

快速排序

3、氣泡排序

public void bubbleSort(int[] a){
 int temp=0;
 for(int i=0;i<a.length;i++){
  for(int j=i;j<a.length;j++){
   if(a[i]>a[j]){
    temp=a[i];
    a[i]=a[j];
    a[j]=temp;
   }
  }
 }
}
氣泡排序(Bubble Sort)比較簡單就不講了。

時間複雜度O(n2),穩定。

4、快速排序

public void QuickSort(int[] a,int low,int high){
 int dp;
 if(low<high){
  dp=partition(a,low,high);
  QuickSort(a,low,dp-1);
  QuickSort(a,dp+1,high);
 }
}
public static int partiton(int[] a,int left,int right({
 int pivot=a[left];
 while(left<right){
  while(left<right&&a[right]>=pivot){
   right--;
  }
  if(left<right){
   a[left++]=a[right];
  }
  while(left<right&&a[left<=pivot){
   left++;
  }
  if(left<right){
   a[right--]=a[left];
  }
 } 
 a[left]=pivot;
 return left;
}


快速排序(Quick Sort)是對氣泡排序的一種改進:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。一趟排序的詳細說明:設樞軸記錄的關鍵字為pivotkey,則首先從high所指位置起向前搜尋找到第一個關鍵字小於pivotkey的記錄和樞軸記錄交換,然後從low所指位置起向後搜尋,找到第一個關鍵字大於pivotkey的記錄和樞軸記錄交換,重複步驟直到low=high。

時間複雜度O(nlogn),空間複雜度O(logn),不穩定。平均效能最好!!!

選擇排序

5、簡單選擇排序

public SelectSort(int[] a){
 int min=0,temp=0;
 for(int i=0;i<a.length;i++){
  min=i;
  for(int j=i+1j<a.length;j++){
   if(a[j]<a[min])
    min=j;
  }
  if(min!=i){
   a[i]<->a[min];
  }
 }
}
選擇排序(Simple Selection Sort)是選擇關鍵字最小的記錄作為有序序列的第i個記錄。

時間複雜度O(n2),不穩定。

6、堆排序

public void HeapSort(int[] a){
 for(int i=0;i<a.length;i++){
  createMaxHeap(a,a.length-1-i);
  swap(a,0,a.length-1-i);
 }
}
public static void createMaxHeap(int[] a,int last){
 for(int i=(last-1)/2;i>=0;i--){
  int k=i;//儲存當前節點
  while(a*k+1<=last){//當前節點存在子節點
   int big=2*k+1;
   if(big<last){//如果右子節點存在
    if(a[big]<<a[big+1])
     big++;
   }
   if(a[k]<a[big]){
    swap(a,k,big);
    k=big;
   }else{
    break;
   }
  }
 }
} 
pubilc static void swap(int[] a,int i,int j){
 if(i==j){
  return;
 }
 a[i]<->a[j];
}
堆排序(Heap Sort)每一趟排序的基本操作將當前無序區的堆頂記錄R[1]和該區間的最後一個記錄交換,然後將新的無序區調整為堆。

時間複雜度O(nlogn),空間複雜度O(1)。

歸併排序

7、2路歸併排序

public void Sort(int[] a,int low,int high){
 int mid=(low+high)/2;
 if(low<high){
  Sort(a,low,mid);//左邊
  Sort(a,mid+1,high);//右邊
  merge(a,low,mid,high);
 }
}
public void merge(int[] a,int low,int mid,int high){
 int[] temp=new int[high-low+1];
 int i=low;
 int j=high;
 int k=0;
 while(i<=mid&&j<=high){
  if(a[i]<a[j]){
   temp[k++]=a[i++];
  }else{
   temp[k++]=a[j++];
  }
 }//while
 
 while(i<mid){
  temp[k++]=a[i++];
 } 
<pre name="code" class="java"> while(j<high){
  temp[k++]=a[j++];
 }
for(int x=0;x<temp.length;x++){
a[x+low]=temp[x];
}
}
2路-歸併排序(Merging Sort)是將兩個有序表合併成一個新的有序表。

時間複雜度O(nlogn),空間複雜度O(n),穩定。

計數排序

8、計數排序

public CountSort(int[] a){
 int k=a.lenght;
 int[] res=new int[k];
 int count[]=new int[k];
 for(int i=0;i<k;i++){//初始化
  count[i]=0;
 }
 //將陣列中的重複的次數
 for(int i=0;i<a.length;i++){
  count[a[i]]=count[a[i]+1];
 }
 for(int i=1;i<k;i++){
  count[i]=count[i]+count[i-1];
 }
 //將陣列a中的元素按順序複製到res中
 for(int i=a.length-1;i>=0;i--){
  res[count[a[i]]-1]=a[i];
  count[a[i]]--;
 }
}
計數排序不需要倆個數之間的對比呦~