常用的排序演算法及其適用場景
1.介紹
常用的排序演算法主要有氣泡排序,選擇排序,插入排序,希爾排序,堆排序,歸併排序,快速排序,桶排序等。
2.穩定性
其中氣泡排序,插入排序,是穩定的排序演算法;選擇排序,希爾排序,堆排序,歸併排序,快速排序是不穩定的排序演算法。
3.排序演算法的實現
3.1氣泡排序
氣泡排序的時間複雜度為o(n*n),空間複雜度為o(1),在資料有序的時候時間複雜度可以達到o(n)。適用的情景為資料量量不大,對穩定性有要求,且資料基本有序的情況下。這裡列舉了氣泡排序的3種實現方式,只有第三種實現方式在最好的情況下可以達到o(n)的時間複雜度,其常見實現方式如下:
// 氣泡排序1
public
int sort_bubble1(int array) }}
return
array;
}// 氣泡排序2
public
int sort_bubble2(int array) }}
return
array;
}// 氣泡排序3
public
int sort_bubble3(int array)
}if (!flag)
break;
}return
array;
}
3.2選擇排序
選擇排序的時間複雜度為o(n*n),空間複雜度為o(1),由於每次選出待排序資料中的最小值(增序)或最大值(降序)插入到當前的有序佇列中,相對於氣泡排序減少了交換的次數。當資料量不大,且對穩定性沒有要求的時候,適用於選擇排序。其**如下:
// 簡單選擇排序
public
int sort_******(int array)
if (min != i)
}return
array;
}
3.3插入排序
插入排序的時間複雜度為o(n*n),空間複雜度為o(1),最好的情況下即當資料有序時可以達到o(n)的時間複雜度,其排序的思想非常類似於我們打撲克牌的時對手裡的牌進行排序的過程,選出乙個值,將其插入在合適的排序位置。適用於資料量不大,對演算法的穩定性有要求,且資料區域性或者整體有序的情況。其**如下:
// 插入排序
public
int sort_insert(int array)
array[j + 1] = temp;}}
return
array;
}
3.4希爾排序
希爾排序時間複雜度為o(nlogn)到o(n*n)之間,空間複雜度為o(1),其排序的效率受到比較距離大小的影響。和插入排序的過程相似,相對於插入排序而言,比較較遠距離的資料,使得資料移動跨過多個元素,進行一次比較可能會消除多個元素的交換。其實現**如下:
// 希爾排序
public
int sort_hill(int array)
array[j + increment] = temp;}}
} while (increment > 1);
return
array;
}
3.5堆排序
堆排序的時間複雜度為o(nlog),空間複雜度為o(1)。實現原理是根據大頂堆或小頂堆得資料結構原理,對待排序資料進行調整,最終達到整體有序的效果,其**如下:
// 堆排序
private
void heap_adjust(int array, int s, int len)
array[s] = temp;
}public
int sort_heap(int array)
for (int j = len - 1; j > 0; j--)
return
array;
}
這裡需要注意的是搞清楚完全二叉樹的父節點和子節點的關係。
對於角標從0開始的元素,其節點關係如下:
雙親:(i-1)/2
左孩子:2*i+1
右孩子:2*i+2
對於角標從1開始的元素,其節點關係如下:
雙親:i/2
左孩子:2*i
右孩子:2*i+1
3.6歸併排序
歸併排序的時間複雜度為o(nlog),空間複雜度為o(n),其需要借助額外的儲存空間,是高階排序演算法中,唯一乙個穩定的排序演算法,當資料量較大時,要注意考慮記憶體空間的開銷。這裡列舉了其兩種實現方式,其中第一種相對而言更加容易理解,其**如下:
// 歸併排序1
private
void merge(int array, int start, int m, int end)
for (int r = 0; r <= m - i; r++)
for (int r = 0; r <= end - j; r++)
system.arraycopy(tmp, 0, array, start, tmp.length);
}private
void m_sort(int array, int start, int end)
public
int sort_merger(int array)
// 歸併排序2
private
void merge(int array, int copy_array, int start, int m, int end)
for (int i = 0; i <= m - start; i++)
for (int i = 0; i <= end - j; i++)
}private
void m_sort(int array, int copy_array, int start, int end) else
}public
int sort_merger(int array)
3.7快速排序
快速排序算發的時間複雜度為o(nlogn),由於快速排序使用遞迴的方式實現,因此空間複雜度為o(nlogn)到o(n)之間。快速排序的思想是設定乙個資料作為分割線,將小於它的資料交換至其左側,大於它的資料交換到它的右側(當資料增序排列的時候)。由於快速排序的原理,常用於查詢一組中前k大的資料。其**如下:
// 快速排序
private
int partion(int array, int low, int high)
array[low] = mid;
system.out.println("array is:" + arrays.tostring(array));
system.out.println("low is:" + low + ";high is:" + high + ";index is:" + low);
return low;
}private
void sort(int array, int low, int high)
}public
int sort_quick(int array)
3.8桶排序
桶排序的時間複雜度為o(n),是一種簡單快速的排序演算法,也有較大的侷限性,僅適用於資料的分布相對比較集中的時候,其原理是建立乙個包含一定數目桶的表,將待排序的資料通過雜湊演算法雜湊到桶中,然後再遍歷桶的到有序的資料。下面舉個例子來說明:
比如待排序的資料集合為[50,52,59,45,51,48,50,55,56,57],這個陣列比較明顯的特點是資料分布在45~59之間,範圍跨度區間為15(59-45+1),因此可以建立乙個長度為15的陣列array,即長度為15的桶,其初始值為0,然後遍歷待排序陣列,將待排序元素的值m減45得到對應桶的角標,將其加1,即array[m-45]++,當將待排序資料遍歷完成之後,遍歷我們建立的資料,將值不為0的角標輸出即可,輸出的時候需要再將角標的值加上45。
常用的排序演算法及其適用場景
常用的排序演算法主要有氣泡排序,選擇排序,插入排序,希爾排序,堆排序,歸併排序,快速排序,桶排序等。穩定的排序演算法 氣泡排序,插入排序 不穩定的排序演算法 選擇排序,希爾排序,堆排序,歸併排序,快速排序。3.1氣泡排序 氣泡排序的時間複雜度為o n n 空間複雜度為o 1 在資料有序的時候時間複雜...
TiDB 的適用場景和不適用場景
典型的oltp場景 當您需要對海量資料 數十億行 進行隨機 實時讀 寫訪問時 實時 htap 場景 實時htap 混合事務 分析處理 要是有乙個使用tidb的類似oltp的場景,並且希望在tiflash的幫助下原地進行 olap分析時,新鮮的資料,對oltp效能無干擾 資料整合 有多個資料來源時,可...
Java常用集合包適用場景
1.arraylist 基於陣列方式實現,無容量的限制。在執行插入元素時可能要擴容,在刪除元素時並不會減少陣列的容量。如果希望相應的縮小陣列容量,可以呼叫trimtosize 在查詢元素時要遍歷陣列,對於非null的元素採取equals的方式尋找。非執行緒安全。2.linkedlist 基於雙向鍊錶...