演算法01 七大排序之:氣泡排序和快速排序
排序是我們生活中經常會面對的問題。同學們做操時會按照從矮到高排列;老師檢視上課出勤情況時,會按學生學號順序點名;高考錄取時,會按成績總分降序依次錄取等。排序是資料處理中經常使用的一種重要的運算,它在我們的程式開發中承擔著非常重要的角色。
排序分為以下四類共七種排序方法:
交換排序:
① 氣泡排序 ② 快速排序
選擇排序:
③ 直接選擇排序 ④ 堆排序
插入排序:
⑤ 直接插入排序 ⑥ 希爾排序
合併排序:
⑦ 合併排序
這篇文章主要總結的是交換排序(即氣泡排序和快速排序),交換排序的基本思想是:兩兩比較待排序元素,如果發現兩個元素的次序相反時即進行交換,直到所有元素都沒有反序時為止。我會從以下幾個方面進行總結:
1、氣泡排序及演算法實現
2、快速排序及演算法實現
3、氣泡排序VS快速排序
1、氣泡排序及演算法實現
什麼是氣泡排序呢?氣泡排序是一種簡單的排序方法,它的基本思想是:通過相鄰兩個元素之間的比較和交換,使較大的元素逐漸從前面移向後面(升序),就像水底下的氣泡一樣逐漸向上冒泡,所以被稱為“冒泡”排序。氣泡排序的最壞時間複雜度為O(n2),平均時間複雜度為O(n2)
下面以一張圖來展示氣泡排序的全過程,其中方括號內為下一輪要排序的元素,方括號後面的第一個元素為本輪排序浮出來的最大元素。
1-1、示意圖
1-2、程式碼
氣泡排序演算法的程式碼實現:
BubbleSort.java
public class BubbleSort { public static void main(String[] args) { int[] list = {36, 28, 45, 13, 67, 37, 18, 56}; System.out.println("************氣泡排序************"); System.out.println("排序前:"); display(list); System.out.println("排序後:"); bubbleSort(list); display(list); } /** * 遍歷列印 */ public static void display(int[] list) { System.out.println("********展示開始********"); if (list != null && list.length > 0) { for (int num : list) { System.out.print(num + " "); } System.out.println(""); } System.out.println("********展示結束********"); } /** * 氣泡排序演算法 */ public static void bubbleSort(int[] list) { int temp; // 做多少輪排序(最多length-1輪) for (int i = 0; i < list.length - 1; i++) { // 每一輪比較多少個 for (int j = 0; j < list.length - 1 - i; j++) { if (list[j] > list[j + 1]) { // 交換次序 temp = list[j]; list[j] = list[j + 1]; list[j + 1] = temp; } } } } }
測試結果:
2、快速排序及演算法實現
快速排序(Quick Sort) 是對氣泡排序的一種改進方法,在氣泡排序中,進行元素的比較和交換是在相鄰元素之間進行的,元素每次交換隻能移動一個位置,所以比較次數和移動次數較多,效率相對較低。而在快速排序中,元素的比較和交換是從兩端向中間進行的,較大的元素一輪就能夠交換到後面的位置,而較小的元素一輪就能交換到前面的位置,元素每次移動的距離較遠,所以比較次數和移動次數較少,速度較快,故稱為“快速排序”。
快速排序的基本思想是:通過一輪排序將待排序元素分割成獨立的兩部分, 其中一部分的所有元素均比另一部分的所有元素小,然後分別對這兩部分的元素繼續進行快速排序,以此達到整個序列變成有序序列。快速排序的最壞時間複雜度為O(n2),平均時間複雜度為O(n*log2n)
2-1、示意圖
2-2、程式碼
快速排序演算法的程式碼實現:
QuickSort.java
public class QuickSort {
public static void main(String[] args) {
int[] list = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
System.out.println("************快速排序************");
System.out.println("排序前:");
display(list);
System.out.println("排序後:");
quickSort(list, 0, list.length - 1);
display(list);
}
/**
* 快速排序演算法
*/
public static void quickSort(int[] list, int left, int right) {
if (left < right) {
// 分割陣列,找到分割點
int point = partition(list, left, right);
// 遞迴呼叫,對左子陣列進行快速排序
quickSort(list, left, point - 1);
// 遞迴呼叫,對右子陣列進行快速排序
quickSort(list, point + 1, right);
}
}
/**
* 分割陣列,找到分割點
*/
public static int partition(int[] list, int left, int right) {
// 用陣列的第一個元素作為基準數
int first = list[left];
while (left < right) {
while (left < right && list[right] >= first) {
right--;
}
// 交換
swap(list, left, right);
while (left < right && list[left] <= first) {
left++;
}
// 交換
swap(list, left, right);
}
// 返回分割點所在的位置
return left;
}
/**
* 交換陣列中兩個位置的元素
*/
public static void swap(int[] list, int left, int right) {
int temp;
if (list != null && list.length > 0) {
temp = list[left];
list[left] = list[right];
list[right] = temp;
}
}
/**
* 遍歷列印
*/
public static void display(int[] list) {
System.out.println("********展示開始********");
if (list != null && list.length > 0) {
for (int num :
list) {
System.out.print(num + " ");
}
System.out.println("");
}
System.out.println("********展示結束********");
}
}
測試結果:
3、氣泡排序VS快速排序
程式碼如下:
BubbleVsQuick.java
public class BubbleVsQuick {
public static void main(String[] args) {
testQuick();
testBubble();
}
/**
* 測試快速排序耗費的時間
*/
public static void testQuick() {
int[] list = new int[10000];
for (int i = 0; i < 10000; i++) {
list[i] = (int) (Math.random() * 100000);
}
// 快速排序
long start = System.currentTimeMillis();
QuickSort.quickSort(list, 0, list.length - 1);
long end = System.currentTimeMillis();
System.out.println("快速排序耗費的時間:" + (end - start));
display(list);
}
/**
* 測試氣泡排序耗費的時間
*/
public static void testBubble() {
int[] list = new int[10000];
for (int i = 0; i < 10000; i++) {
list[i] = (int) (Math.random() * 100000);
}
// 氣泡排序
long start = System.currentTimeMillis();
BubbleSort.bubbleSort(list);
long end = System.currentTimeMillis();
System.out.println("氣泡排序耗費的時間:" + (end - start));
display(list);
}
/**
* 遍歷列印前10個數
*/
public static void display(int[] list) {
System.out.println("********排序之後的前10個數start********");
if (list != null && list.length > 0) {
for (int i = 0; i < 10; i++) {
System.out.print(list[i] + " ");
}
System.out.println("");
}
System.out.println("********排序之後的前10個數end**********");
System.out.println("");
}
}
測試結果:
可見,快速排序的速度比氣泡排序更快。