快速排序的原理思想及步驟:
其思想是:
a,先選一個基準數,用這個基準數與數列中的每個數都比一遍,
b,以保證:其左邊的元素都不大於它,其右邊的元素都不小於它。
c,這樣,排序問題就被分割爲兩個子區間,再分別對子區間排序就可以了。
其步驟是:
1.先從數列中取出一個數作爲基準數。
2.分區過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。
3.再對左右區間重複第二步,直到各區間只有一個數。
在給算法比較效率的時候,選擇了System.nanoTime()方法:
public static long nanoTime()返回最準確的可用系統計時器的當前值,以毫微秒爲單位。
此方法只能用於測量已過的時間,與系統或鐘錶時間的其他任何時間概念無關。返回值表示從某一固定但任意的時間算起的毫微秒數(或許從以後算起,所以該值可能爲負)。此方法提供毫微秒的精度,但不是必要的毫微秒的準確度。它對於值的更改頻率沒有作出保證。在取值範圍大於約 292 年(263 毫微秒)的連續調用的不同點在於:由於數字溢出,將無法準確計算已過的時間。
例如,測試某些代碼執行的時間長度:
long startTime = System.nanoTime();
// … the code being measured …
long estimatedTime = System.nanoTime() - startTime;
返回:
系統計時器的當前值,以毫微秒爲單位。
由於時間的單位是極其的小,計算機的cpu工作速度有那麼快,如果我們測試的數組不足夠大的話,實驗的結果可能會不明顯。所以我們在這裏設置了一個容量爲1000的數組以供檢驗。
快速排序算法代碼如下:
package kuaipaixu;
public class Kuaipaixu {
public static void main(String[] args) {
int[] a = {4,3,7,1,2,8,6,5}; //測試數組
qso(a, 0, a.length - 1); //調用快速排序
for (int k : a) { //迭代輸出數組
System.out.print(k+" ");
}
}
private static void qso(int a[], int left, int right) {
int i;
int j;
int t;
if (left >= right) return;//遞歸調用中,若left>=right,說明達到遞歸出口,元素已經全部有序
int temp = a[left];//定義a[left]爲切分的基準元素(可優化爲隨機選取基準元素,消除數據依賴)
i = left;
j = right;
while (i != j) {
while (a[j] >= temp && i < j) j--;//從右往左找到需要交換的a[j]位置
while (a[i] <= temp && i < j) i++;//從左往右找到需要交換的a[i]位置
if (i < j) { // 滿足i<j,交換a[i]和a[j]兩個位置
t = a[i];
a[i] = a[j];
a[j] = t;
}
}//若跳出循環,證明i和j相遇
//此時,需要將基準數temp歸位到i==j的那個位置
a[left] = a[i];
a[i] = temp;
//將已經歸爲的左邊和右邊的數,再次遞歸調用快速排序
qso(a,left,i-1);
qso(a,i+1,right);
}
}
運行結果爲:
冒泡排序的原理思想及步驟:
算法原理:
a,每次對相鄰的兩個元素進行比較,若前者大於後者則進行交換,
b,如此一趟下來最後一趟的就是最大元素,重複以上的步驟,即可完成冒泡排序。
基本步驟:
•比較相鄰的元素,如果前一個比後一個大,就把它們兩個調換位置
•對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是 最大的數
•針對所有的元素重複以上的步驟,除了最後一個
•持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較
冒泡排序算法代碼如下:
package maopao;
public class Maopao{
public static void main(String[] args) { //主函數;
int[] arr = new int[]{19,29,39,49,59}; //創建數組;
for(int i = 0;i <arr.length-1;i++){ //外循環,比較的輪數爲i;array.length是數組的長度,遞增
for(int j = 0;j <arr.length-1-i;j++){ //一次換位爲一次內循環,每輪數中兩兩比較的次數爲j;
//數兩兩比較的交換
if(arr[j] >arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
//遍歷數組;
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
運行結果如下:
冒泡排序和快速排序的區別:
冒泡排序是從最底層元素開始比較,(與其上的元素比較)
小於就往上再比,大於就交換,再用較小的往上比較,直到最高層,
第一次把最小的放到最上層,第二次把第二小的放到第二層,以次類推;
快速排序是先找到一個軸值,比較時把所有比軸值小的放到軸值的左邊,
比軸值大的放到右邊,再在兩邊各自選取軸值再按前面排序,直到完成.
冒泡排序和快速排序的代碼效率
package test;
import java.util.ArrayList;
import java.util.List;
public class Bijiao {
@SuppressWarnings("unused")
public static void main(String[] args) {
// 創建集合添加數
List<Integer> list = new ArrayList<Integer>();
Integer a = 40;
for (int i = 0; i < 10000; i++) {
list.add(a);
a++;
}
// 把集合添加的數據轉爲數組
Integer[] arr = new Integer[list.size()];
for (int i = 0; i < list.size(); i++) {
arr[i] = list.get(i);
}
// 定義冒泡,選擇,快速排序
long m, x, k;
// 冒泡排序調用
long start = System.currentTimeMillis();
Integer[] bubbleList = listAll(arr);
long end = System.currentTimeMillis();
m = end - start;
// 選擇排序調用
start = System.currentTimeMillis();
Integer[] listAll = listAll(arr);
end = System.currentTimeMillis();
x = end - start;
// 快速排序調用
start = System.currentTimeMillis();
Integer[] fastSort = fastSort1(arr, 0, arr.length - 1);
end = System.currentTimeMillis();
k = end - start;
System.out.println("冒泡=" + m);
System.out.println("快速=" + k);
}
private static Integer[] fastSort1(Integer[] arr, int i, int j) {
// TODO Auto-generated method stub
return null;
}
// 冒泡排序
private static Integer[] listAll(Integer[] arr) {
for (Integer i = 0; i < arr.length - 1; i++) {
for (Integer j = 0; j < arr.length - i - 1; j++) {
Integer temp = 0;
// System.out.println(Air[j]+"---"+air[j+1]);
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
// 選擇排序
private static Integer[] listAll1(Integer[] arr) {
for (Integer i = 0; i < arr.length - 1; i++) {
for (Integer j = i + 1; j < arr.length; j++) {
Integer temp = 0;
// System.out.println(arr[i]+"---"+arr[j]);
if (arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
public static Integer[] fastSort(Integer[] strDate, int left, int right) {
Integer middle, tempDate;
Integer i, j; // i爲起始位置,j爲最後位置
i = left;
j = right;
middle = strDate[(i + j) / 2];
do {
while (strDate[i].compareTo(middle) < 0 && i < right) {
i++; // 找出左邊中間值大的數
}
while (strDate[j].compareTo(middle) > 0 && j > left) {
j--; // 找出右邊中間值小的數
}
if (i <= j) { // 將左邊大的數和右邊小的數進行替換
tempDate = strDate[i];
strDate[i] = strDate[j];
strDate[j] = tempDate;
i++;
j--;
}
} while (i <= j); // 當兩者交錯時停止
if (i < right) { // 如果i小於調用時右邊的數
fastSort1(strDate, i, right);
}
if (j > left) { // 如果j大於調用時左邊的數
fastSort1(strDate, left, j);
}
return strDate;
}
}
運行結果如下:
總結:
在此實驗中,對於相同的實驗數組,在快速排序算法和冒泡排序兩種算法的在同樣環境下運行結果差異比較明顯,在這個實驗中,快速排序算法處理的效率大約是冒泡排序效率的一百倍。所以在處理數據,選擇排序方法時,選擇快速排序效率會比冒泡排序高很多。