1. 程式人生 > >氣泡排序與快速排序比較

氣泡排序與快速排序比較

}

例子為從小到大排序,

原始待排序陣列| 6 | 2 | 4 | 1 | 5 | 9 |

第一趟排序(外迴圈)

第一次兩兩比較6 > 2交換(內迴圈)

交換前狀態| 6 | 2 | 4 | 1 | 5 | 9 |

交換後狀態| 2 | 6 | 4 | 1 | 5 | 9 |

第二次兩兩比較,6 > 4交換

交換前狀態| 2 | 6 | 4 | 1 | 5 | 9 |

交換後狀態| 2 | 4 | 6 | 1 | 5 | 9 |

第三次兩兩比較,6 > 1交換

交換前狀態| 2 | 4 | 6 | 1 | 5 | 9 |

交換後狀態| 2 | 4 | 1 | 6 |

 5 | 9 |

第四次兩兩比較,6 > 5交換

交換前狀態| 2 | 4 | 1 | 6 | 5 | 9 |

交換後狀態| 2 | 4 | 1 | 5 | 6 | 9 |

第五次兩兩比較,6 < 9不交換

交換前狀態| 2 | 4 | 1 | 5 | 6 | 9 |

交換後狀態| 2 | 4 | 1 | 5 | 6 | 9 |

第二趟排序(外迴圈)

第一次兩兩比較2 < 4不交換

交換前狀態| 2 | 4 | 1 | 5 | 6 | 9 |

交換後狀態| 2 | 4 | 1 | 5 | 6 | 9 |

第二次兩兩比較,4 > 1交換

交換前狀態| 2 | 4 | 1 |

 5 | 6 | 9 | 
交換後狀態| 2 | 1 | 4 | 5 | 6 | 9 |

第三次兩兩比較,4 < 5不交換

交換前狀態| 2 | 1 | 4 | 5 | 6 | 9 | 
交換後狀態| 2 | 1 | 4 | 5 | 6 | 9 |

第四次兩兩比較,5 < 6不交換

交換前狀態| 2 | 1 | 4 | 5 | 6 | 9 |

交換後狀態| 2 | 1 | 4 | 5 | 6 | 9 |

第三趟排序(外迴圈)

第一次兩兩比較2 > 1交換

交換後狀態| 2 | 1 | 4 | 5 | 6 | 9 |

交換後狀態| 1 | 2 | 4 | 5 | 6 | 9 |

第二次兩兩比較,2 < 4不交換

交換後狀態| 1 | 2 | 4 | 5 | 6 | 9 | 
交換後狀態| 1 | 2 | 4 | 5 | 6 | 9 |

第三次兩兩比較,4 < 5不交換

交換後狀態| 1 | 2 | 4 | 5 | 6 | 9 | 
交換後狀態| 1 | 2 | 4 | 5 | 6 | 9 |

第四趟排序(外迴圈)無交換

第五趟排序(外迴圈)無交換

效率分析
      1.時間複雜度:O(n^2)

氣泡排序耗時的操作有:比較 + 交換(每次交換兩次賦值)。時間複雜度如下:

1)最好情況:序列是升序排列,在這種情況下,需要進行的比較操作為(n-1)次。交換操作為0次。即O(n)

2)最壞情況:序列是降序排列,那麼此時需要進行的比較共有n(n-1)/2次。交換運算元和比較運算元一樣。即O(n^2)

3)漸進時間複雜度(平均時間複雜度):O(n^2)

2.空間複雜度:O(1)

從實現原理可知,氣泡排序是在原輸入陣列上進行比較交換的(稱“就地排序”),所需開闢的輔助空間跟輸入陣列規模無關,所以空間複雜度為:O(1)

      3 .    穩定性

       氣泡排序是穩定的,不會改變相同元素的相對順序。
快速排序

(一)概念及實現

思想:分治策略。

快速排序的原理:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序。

"保證列表的前半部分都小於後半部分"就使得前半部分的任何一個數從此以後都不再跟後半部分的數進行比較了,大大減少了數字間的比較次數。

具體如下(實現為升序)

設陣列為a[0n]

1.陣列中找一個元素做為基準(pivot),通常選陣列的第一個數。

2.對陣列進行分割槽操作。使基準元素左邊的值都小於pivot,基準元素右邊的值都大於等於pivot

3.pivot值調整到分割槽後的正確位置。

4.將基準兩邊的分割槽序列,分別進行步驟1~3。(遞迴)

5.重複步驟1~4,直到排序完成。
public static void main(String[] arg){ Test test=new Test(); int[] x = { 49, 52, 65,12,45,5 }; test.kuaisu(x, 6); }
pub   public void kuaisu(int[] a,int num){ if(num>1){//如果長度小於2,則步不用排序 _quick_sort(a, 0, num - 1); } for(int ii=0;ii<a.length;ii++){ System.out.print(" "+a[ii]+" "); } } public void _quick_sort(int[] arrays, int start, int end){ if(start>=end){       return; } int i=start; int j=end; int value=arrays[i]; boolean flag = true; while (i != j) { if (flag) { if (value > arrays[j]) {    int temp = arrays[i];    arrays[i] = arrays[j];    arrays[j] = temp;    flag=false; }else{ j--; } }else{ if(value<arrays[i]){   int temp = arrays[i];   arrays[i] = arrays[j];   arrays[j] = temp;   flag=true; }else{ i++; } } } for (int k = 0; k < arrays.length; k++) { System.out.print(arrays[k] + " ");    } System.out.println(); _quick_sort(arrays, start, j-1); _quick_sort(arrays, i+1, end); }

(二)演算法複雜度

1.時間複雜度:O(nlog2n)

快速排序耗時的操作有:比較 + 交換(每次交換兩次賦值)。時間複雜度如下:

1)最好情況:選擇的基準值剛好是中間值,分割槽後兩分割槽包含元素個數接近相等。因為,總共經過x次分割槽,根據2^x<=n得出x=log2n,每次分割槽需用n-1個元素與基準比較。所以O(nlog2n)

2)最壞情況:每次分割槽後,只有一個分割槽包含除基準元素之外的元素。這樣就和氣泡排序一樣慢,需O(n^2)

3)漸進時間複雜度(平均時間複雜度):O(nlog2n)

2.空間複雜度:O(1)

從實現原理可知,快速排序是在原輸入陣列上進行比較分割槽的(稱“就地排序”),所需開闢的輔助空間跟輸入陣列規模無關,所以空間複雜度為:O(1)

(三)穩定性

快速是不穩定的,會改變相同元素的相對順序。如示例,以第一個基準89排序時,首先將最後一個元素-7移到了第一個分割槽的第一個位置上。改變了與第二個-7的相對順序。