1)冒泡排序
/**
* 冒泡排序,時間複雜度 O(n^2) 最優 O(n) 最差 O(n^2) 穩定
* @param arr
*/
public static void bubbleSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
for(int j=0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
2)選擇排序
/**
* 選擇排序,時間複雜度 O(n^2) 最優 O(n^2) 最差 O(n^2) 不穩定
* @param arr
* @param start
* @param end
*/
public static void selectSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
int min = i;
for(int j=i+1;j<arr.length;j++){
if(arr[j]<arr[min]){
int temp = arr[j];
arr[j] = arr[min];
arr[min] = temp;
}
}
}
}
3)插入排序
/**
* 插入排序,時間複雜度 O(n^2) 最優 O(n) 最差 O(n^2) 穩定
* @param arr
*/
public static void insertSort(int[] arr){
for(int i=1;i<arr.length;i++){
//拿出一張牌
int get = arr[i];
int j=i-1;
while(j>=0&&get<arr[j]){
arr[j+1]=arr[j];
j--;
}
//插入
arr[j+1]=get;
}
}
4)二分法插入排序
/**
* 二分法插入排序,時間複雜度 O(n^2) O(nlogn) 最差 O(n^2) 穩定
* @param arr
*/
public static void insertSortDichotomy(int[] arr){
for(int i=1;i<arr.length;i++){
//拿出一張牌
int get = arr[i];
int left=0;
int right = i-1;
//二分法查找插入位置
while(left<=right){
int mid = (left+right)/2;
if(arr[mid]>get){
right=mid-1;
}else{
left=mid+1;
}
}
for(int j=i-1;j>=left;j--){//把插入位置之後的牌依次後挪,騰出位置
arr[j+1]=arr[j];
}
//插入牌
arr[left]=get;
}
}
5)快速排序
/**
* 快速排序,時間複雜度 O(nlogn) 最差情況爲O(n^2),最優 O(logn)
* @param arr
*/
public static void quickSort(int[] arr){
quickSort(arr,0,arr.length-1);
}
public static void quickSort(int[] arr,int start,int end){
//遞歸出口
if(start>=end){
return;
}
int index = arr[start];
int i= start;
int j = end;
while(i<j){
//從右往左,找比基準數小的數
while(i<j&&arr[j]>index){
j--;
}
if(i<j){
arr[i] = arr[j];
}
//從左往右,找比基準數大的數
while(i<j&&arr[i]<=index){
i++;
}
if(i<j){
arr[j] = arr[i];
}
arr[i] = index;
}
//分治法-對基準數左右進行快速排序
quickSort(arr,start,i-1);
quickSort(arr,i+1,end);
}
6)歸併排序
//歸併排序 ,時間複雜度 O(nlogn) 最差情況爲 O(nlogn),最優 O(nlogn) 穩定
public static void mergeSort(int[] arr){
mergeSort(arr,0,arr.length-1);
}
public static void mergeSort(int[] arr, int start, int end){
if(start<end){
int mid = (start+end)/2;
mergeSort(arr,start,mid);//左邊有序
mergeSort(arr,mid+1,end);//右邊有序
Merge(arr,start,mid,end);
}
}
public static void Merge(int[] arr,int start,int mid,int end){
int[] temp = new int[arr.length];
int i = start;
int j = mid+1;
int k = start;
//從兩邊取,直到一邊取完
while(i<=mid&&j<=end){
if(arr[i]<arr[j]){//拿出較小,放入新數組
temp[k++] = arr[i++];
}else{
temp[k++] = arr[j++];
}
}
//在剩下的一邊中依次取
while (i <= mid)
temp[k++] = arr[i++];
while (j <= end)
temp[k++] = arr[j++];
for(i=start;i<=end;i++){//將排好數組覆蓋給原數組
arr[i] = temp[i];
}
}
7)堆排序
以數組形式代替堆結構,實現堆排序
/**
* 堆排序,時間複雜度 O(nlogn) 最差情況爲 O(nlogn),最優 O(nlogn) 不穩定
* @param arr
*/
public static void heapSort(int[] arr){
//建立初始堆
for(int i=(arr.length-1)/2;i>=0;i--){
heapOne(arr,arr.length,i);
}
//依次拿出堆頂元素
int n = arr.length;
int[] temp = new int[arr.length];
while(n>0){
temp[arr.length-n]=arr[0];
arr[0] = arr[n-1];//最後一個葉子節點移動到堆頂
n--;
heapOne(arr,n,0);
}
for(int j=0;j<arr.length;j++){//將排好數組覆蓋給原數組
arr[j] = temp[j];
}
}
//做篩選,合格的二叉堆
public static void heapOne(int[] arr,int n,int k){
int k1 = 2*k+1;
int k2 = 2*k+2;
if(k1>n&&k2>n)//已經沒有子節點,自己已經是葉子了
return;
int child_left = Integer.MAX_VALUE;
int child_right = Integer.MAX_VALUE;
if(k1<n){
child_left = arr[k1];
}
if(k2<n){
child_right = arr[k2];
}
if(arr[k]<child_left&&arr[k]<child_right){
return;//滿足堆的要求
}
if(child_left<child_right){//找出較小的進行交換
int temp = arr[k];
arr[k] = arr[k1];
arr[k1] = temp;
heapOne(arr,n,k1);//篩選子節點
}else{
int temp = arr[k];
arr[k] = arr[k2];
arr[k2] = temp;
heapOne(arr,n,k2);//篩選子節點
}
參考資料:http://www.cnblogs.com/eniac12/p/5329396.html