大概花了一週的時間把八大基礎排序過了一遍,這篇博文主要是用來回顧一下八大基礎排序的要點和一些總結~html
回顧:java
總的來講:快速排序是用得比較普遍的一個排序,也是常常出現的一個排序,應該重點掌握~git
思路:github
n-1
趟排序,好比10個數,須要9趟排序代碼實現要點:算法
//外層循環是排序的趟數
for (int i = 0; i < arrays.length -1 ; i++) {
//每比較一趟就從新初始化爲0
isChange = 0;
//內層循環是當前趟數須要比較的次數
for (int j = 0; j < arrays.length - i - 1; j++) {
//前一位與後一位與前一位比較,若是前一位比後一位要大,那麼交換
if (arrays[j] > arrays[j + 1]) {
temp = arrays[j];
arrays[j] = arrays[j + 1];
arrays[j + 1] = temp;
//若是進到這裏面了,說明發生置換了
isChange = 1;
}
}
//若是比較完一趟沒有發生置換,那麼說明已經排好序了,不須要再執行下去了
if (isChange == 0) {
break;
}
}
System.out.println("公衆號Java3y" + arrays);
複製代碼
思路:shell
n-1
趟排序,好比10個數,須要9趟排序代碼實現要點:c#
//外層循環控制須要排序的趟數
for (int i = 0; i < arrays.length - 1; i++) {
//新的趟數、將角標從新賦值爲0
pos = 0;
//內層循環控制遍歷數組的個數並獲得最大數的角標
for (int j = 0; j < arrays.length - i; j++) {
if (arrays[j] > arrays[pos]) {
pos = j;
}
}
//交換
temp = arrays[pos];
arrays[pos] = arrays[arrays.length - 1 - i];
arrays[arrays.length - 1 - i] = temp;
}
System.out.println("公衆號Java3y" + arrays);
複製代碼
思路:api
n-1
趟排序,好比10個數,須要9趟排序代碼實現:數組
//臨時變量
int temp;
//外層循環控制須要排序的趟數(從1開始由於將第0位當作了有序數據)
for (int i = 1; i < arrays.length; i++) {
temp = arrays[i];
//若是前一位(已排序的數據)比當前數據要大,那麼就進入循環比較[參考第二趟排序]
int j = i - 1;
while (j >= 0 && arrays[j] > temp) {
//日後退一個位置,讓當前數據與以前前位進行比較
arrays[j + 1] = arrays[j];
//不斷往前,直到退出循環
j--;
}
//退出了循環說明找到了合適的位置了,將當前數據插入合適的位置中
arrays[j + 1] = temp;
}
System.out.println("公衆號Java3y" + arrays);
複製代碼
思路:微信
代碼實現:
/** * 快速排序 * * @param arr * @param L 指向數組第一個元素 * @param R 指向數組最後一個元素 */
public static void quickSort(int[] arr, int L, int R) {
int i = L;
int j = R;
//支點
int pivot = arr[(L + R) / 2];
//左右兩端進行掃描,只要兩端尚未交替,就一直掃描
while (i <= j) {
//尋找直到比支點大的數
while (pivot > arr[i])
i++;
//尋找直到比支點小的數
while (pivot < arr[j])
j--;
//此時已經分別找到了比支點小的數(右邊)、比支點大的數(左邊),它們進行交換
if (i <= j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
}
//上面一個while保證了第一趟排序支點的左邊比支點小,支點的右邊比支點大了。
//「左邊」再作排序,直到左邊剩下一個數(遞歸出口)
if (L < j)
quickSort(arr, L, j);
//「右邊」再作排序,直到右邊剩下一個數(遞歸出口)
if (i < R)
quickSort(arr, i, R);
}
複製代碼
思路:
代碼實現:
public static void main(String[] args) {
int[] arrays = {9, 2, 5, 1, 3, 2, 9, 5, 2, 1, 8};
mergeSort(arrays, 0, arrays.length - 1);
System.out.println("公衆號:Java3y" + arrays);
}
/** * 歸併排序 * * @param arrays * @param L 指向數組第一個元素 * @param R 指向數組最後一個元素 */
public static void mergeSort(int[] arrays, int L, int R) {
//若是隻有一個元素,那就不用排序了
if (L == R) {
return;
} else {
//取中間的數,進行拆分
int M = (L + R) / 2;
//左邊的數不斷進行拆分
mergeSort(arrays, L, M);
//右邊的數不斷進行拆分
mergeSort(arrays, M + 1, R);
//合併
merge(arrays, L, M + 1, R);
}
}
/** * 合併數組 * * @param arrays * @param L 指向數組第一個元素 * @param M 指向數組分隔的元素 * @param R 指向數組最後的元素 */
public static void merge(int[] arrays, int L, int M, int R) {
//左邊的數組的大小
int[] leftArray = new int[M - L];
//右邊的數組大小
int[] rightArray = new int[R - M + 1];
//往這兩個數組填充數據
for (int i = L; i < M; i++) {
leftArray[i - L] = arrays[i];
}
for (int i = M; i <= R; i++) {
rightArray[i - M] = arrays[i];
}
int i = 0, j = 0;
// arrays數組的第一個元素
int k = L;
//比較這兩個數組的值,哪一個小,就往數組上放
while (i < leftArray.length && j < rightArray.length) {
//誰比較小,誰將元素放入大數組中,移動指針,繼續比較下一個
if (leftArray[i] < rightArray[j]) {
arrays[k] = leftArray[i];
i++;
k++;
} else {
arrays[k] = rightArray[j];
j++;
k++;
}
}
//若是左邊的數組還沒比較完,右邊的數都已經完了,那麼將左邊的數抄到大數組中(剩下的都是大數字)
while (i < leftArray.length) {
arrays[k] = leftArray[i];
i++;
k++;
}
//若是右邊的數組還沒比較完,左邊的數都已經完了,那麼將右邊的數抄到大數組中(剩下的都是大數字)
while (j < rightArray.length) {
arrays[k] = rightArray[j];
k++;
j++;
}
}
複製代碼
思路:
代碼實現:
public static void main(String[] args) {
int[] arrays = {6, 3, 8, 7, 5, 1, 2, 23, 4321, 432, 3,2,34234,2134,1234,5,132423, 234, 4, 2, 4, 1, 5, 2, 5};
for (int i = 0; i < arrays.length; i++) {
//每完成一次建堆就能夠排除一個元素了
maxHeapify(arrays, arrays.length - i);
//交換
int temp = arrays[0];
arrays[0] = arrays[(arrays.length - 1) - i];
arrays[(arrays.length - 1) - i] = temp;
}
System.out.println("公衆號:Java3y" + arrays);
}
/** * 完成一次建堆,最大值在堆的頂部(根節點) */
public static void maxHeapify(int[] arrays, int size) {
for (int i = size - 1; i >= 0; i--) {
heapify(arrays, i, size);
}
}
/** * 建堆 * * @param arrays 看做是徹底二叉樹 * @param currentRootNode 當前父節點位置 * @param size 節點總數 */
public static void heapify(int[] arrays, int currentRootNode, int size) {
if (currentRootNode < size) {
//左子樹和右字數的位置
int left = 2 * currentRootNode + 1;
int right = 2 * currentRootNode + 2;
//把當前父節點位置當作是最大的
int max = currentRootNode;
if (left < size) {
//若是比當前根元素要大,記錄它的位置
if (arrays[max] < arrays[left]) {
max = left;
}
}
if (right < size) {
//若是比當前根元素要大,記錄它的位置
if (arrays[max] < arrays[right]) {
max = right;
}
}
//若是最大的不是根元素位置,那麼就交換
if (max != currentRootNode) {
int temp = arrays[max];
arrays[max] = arrays[currentRootNode];
arrays[currentRootNode] = temp;
//繼續比較,直到完成一次建堆
heapify(arrays, max, size);
}
}
}
複製代碼
思路:
代碼思路:
gap = gap / 2
,只是比普通版插入排序多了這麼一個for循環罷了,難度並不大/** * 希爾排序 * * @param arrays */
public static void shellSort(int[] arrays) {
//增量每次都/2
for (int step = arrays.length / 2; step > 0; step /= 2) {
//從增量那組開始進行插入排序,直至完畢
for (int i = step; i < arrays.length; i++) {
int j = i;
int temp = arrays[j];
// j - step 就是表明與它同組隔壁的元素
while (j - step >= 0 && arrays[j - step] > temp) {
arrays[j] = arrays[j - step];
j = j - step;
}
arrays[j] = temp;
}
}
}
複製代碼
思路:
代碼實現:
public static void main(String[] args) {
int[] arrays = {6, 4322, 432, 344, 55, 234, 45, 243, 5, 2, 4, 5, 6, 7, 3245, 345, 345, 234, 68, 65};
radixSort(arrays);
System.out.println("公衆號:Java3y" + arrays);
}
public static void radixSort(int[] arrays) {
int max = findMax(arrays, 0, arrays.length - 1);
//須要遍歷的次數由數組最大值的位數來決定
for (int i = 1; max / i > 0; i = i * 10) {
int[][] buckets = new int[arrays.length][10];
//獲取每一位數字(個、10、百、千位...分配到桶子裏)
for (int j = 0; j < arrays.length; j++) {
int num = (arrays[j] / i) % 10;
//將其放入桶子裏
buckets[j][num] = arrays[j];
}
//回收桶子裏的元素
int k = 0;
//有10個桶子
for (int j = 0; j < 10; j++) {
//對每一個桶子裏的元素進行回收
for (int l = 0; l < arrays.length ; l++) {
//若是桶子裏面有元素就回收(數據初始化會爲0)
if (buckets[l][j] != 0) {
arrays[k++] = buckets[l][j];
}
}
}
}
}
/** * 遞歸,找出數組最大的值 * * @param arrays 數組 * @param L 左邊界,第一個數 * @param R 右邊界,數組的長度 * @return */
public static int findMax(int[] arrays, int L, int R) {
//若是該數組只有一個數,那麼最大的就是該數組第一個值了
if (L == R) {
return arrays[L];
} else {
int a = arrays[L];
int b = findMax(arrays, L + 1, R);//找出總體的最大值
if (a > b) {
return a;
} else {
return b;
}
}
}
複製代碼
對於排序的時間複雜度和穩定性網上的圖也不少不少,我就隨便找一張了(侵刪)
要是對某個排序不太理解的同窗最好是到我寫的單個文章中進行查閱,由於有分解的步驟~
我也將代碼(包括分解過程)上傳到了GitHub上了,算法和數據結構的代碼我都往上面放了,歡迎star~後序還會寫棧、隊列相關的博文,敬請期待...
休閒時間:
參考資料:
若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y