java中最常見的幾種排序方法分別是:冒泡排序、快速排序、選擇排序、插入排序。
1、冒泡排序
算法思想:
從數組中第一個數開始,依次遍歷數組中的每一個數,通過相鄰比較交換,每一輪循環下來找出剩餘未排序數的中的最大數並”冒泡”至數列的頂端。
算法步驟:
(1)從數組中第一個數開始,依次與下一個數比較並次交換比自己小的數,直到最後一個數。如果發生交換,則繼續下面的步驟,如果未發生交換,則數組有序,排序結束,此時時間複雜度爲O(n);
(2)每一輪”冒泡”結束後,最大的數將出現在亂序數列的最後一位。重複步驟(1)。
穩定性:穩定排序。
具體例子如下:
package com.px.cn;
public class MaoPao {
/**
* 冒泡排序
*/
public static int[] sort(int[] array) {
int temp;
// 第一層循環表明比較的輪數, 比如 length 個元素,比較輪數爲 length-1 次(不需和自己比)
for (int i = 0; i < array.length - 1; i++) {
System.out.println("第" + (i + 1) + "輪開始");
// 第二層循環,每相鄰的兩個比較一次,次數隨着輪數的增加不斷減少,每輪確定一個最大的,不需比較那個最大的
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j + 1] < array[j]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
System.out.println("第" + (i + 1) + "輪,第" + (j + 1) + "次比較:");
for (int k : array) {
System.out.print(k + " ");
}
System.out.println();
}
System.out.println("結果:");
for (int k : array) {
System.out.print(k + " ");
}
System.out.println();
}
return array;
}
public static void main(String[] args) {
int[] array = {1, 3, 2, 72,13,21,15,34 };
int[] sorted = sort(array);
System.out.println("最終結果");
for (int i : sorted) {
System.out.print(i + " ");
}
}
}
運行最終結果爲:1 2 3 13 15 21 34 72
2、插入排序
原理:從待排序的n個記錄中的第二個記錄開始,依次與前面的記錄比較並尋找插入的位置,每次外循環結束後,將當前的數插入到合適的位置。
穩定性:穩定排序。
具體例子如下:
package com.px.cn;
/**
* 直接插入排序類
*/
public class ChaRu {
public static void getInsertSort(int[] a) {
if(a == null || a.length == 0) {//判斷數組是否爲空
System.out.println("該數組爲空!");
return;
}
int n = a.length;//將數組的長度賦給n是爲了防止每次for循環中判斷時都調用length方法影響性能
int temp;//放於for循環外面是爲了防止重複創建變量
int j;
for(int i = 1; i < n;i++){//排序的趟數
temp = a[i];//賦給temp是爲了防止索引i之前的元素向後移動覆蓋了索引i的元素
j = i-1;
for(; j>=0&&a[j]>temp; --j) {//將大於i位置元素的元素向後移
a[j+1] = a[j];
}
a[j+1]= temp;//找到i應該在的位置,將值放置此處
}
}
public static void main(String[] args) {
int[] a = {3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34};
getInsertSort(a);
System.out.print("直接插入排序:");
for(int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
}
運行最終結果:1 2 3 3 4 5 6 7 11 23 34 44
3、快速排序
冒泡排序是在相鄰的兩個記錄進行比較和交換,每次交換隻能上移或下移一個位置,導致總的比較與移動次數較多。快速排序又稱分區交換排序,是對冒泡排序的改進,快速排序採用的思想是分治思想。。
算法原理:
(1)從待排序的n個記錄中任意選取一個記錄(通常選取第一個記錄)爲分區標準;
(2)把所有小於該排序列的記錄移動到左邊,把所有大於該排序碼的記錄移動到右邊,中間放所選記錄,稱之爲第一趟排序;
(3)然後對前後兩個子序列分別重複上述過程,直到所有記錄都排好序。
穩定性:不穩定排序。
具體例子如下:
package com.px.cn;
/**
*快速排序
*/
public class KuaiSu {
static int count = 0;
public static void main(String[] args) {
int values[] = { 5, 4, 8, 3, 7, 2, 1, 9, 0, 6 };
qsort(values, 0, (values.length - 1));
System.out.printf("\n\n排序後的結果是:");
for (int i = 0; i < values.length; i++) {
System.out.printf("%d ", values[i]);
}
}
public static void qsort(int values[], int left, int right) {
int tmp = 0;
System.out.printf("\n這個是第%d次排序的結果:", count);
count++;
for (int i = 0; i < values.length; i++) {
System.out.printf("%d ", values[i]);
}
if (left < right) {
tmp = partition(values, left, right);
qsort(values, left, tmp);
qsort(values, tmp + 1, right);
}
}
public static int partition(int values[], int left, int right) {
int i = 0, j = 0;
int key = 0, tmp = 0;
if (null == values) {
return 0;
}
i = left;
j = right;
key = values[left];
// 這個while循環可以實現排序的第一步:分組
while (i < j) {
while (values[j] > key) {
--j;
}
tmp = values[i];
values[i] = values[j];
values[j] = tmp;
while (values[i] < key) {
i++;
}
tmp = values[i];
values[i] = values[j];
values[j] = tmp;
}
return i;
}
}
運行最終結果:0 1 2 3 4 5 6 7 8 9
4、選擇排序
原理:從所有記錄中選出最小的一個數據元素與第一個位置的記錄交換;然後在剩下的記錄當中再找最小的與第二個位置的記錄交換,循環到只剩下最後一個數據元素爲止。
穩定性:不穩定排序。
具體例子如下:
package com.px.cn;
/**
* 選擇排序
*/
public class XuanZ {
public static void selectionSort(int[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
int k = i;
// 找出最小值的小標
for (int j = i + 1; j < n; j++) {
if (a[j] < a[k]) {
k = j;
}
}
// 將最小值放到排序序列末尾
if (k > i) {
int tmp = a[i];
a[i] = a[k];
a[k] = tmp;
}
}
}
public static void main(String[] args) {
int[] b = { 49, 38, 65, 97, 76, 13, 27, 50 };
selectionSort(b);
for (int i : b)
System.out.print(i + " ");
}
}
運行結果如下:13 27 38 49 50 65 76 97