1. 程式人生 > >演算法(一)排序演算法(桶排序、氣泡排序、快速排序)

演算法(一)排序演算法(桶排序、氣泡排序、快速排序)

第一次排序:首先,找一個"基準數",比如5,然後,先從右到左,找到第一個小於基準數的數,4,再從左到右,找到第一個大於基準數的數,9將它們進行交換,5,1,4,26,2,9,5,7,52,21繼續從右到左,尋找小於基準數的數,從左到右,尋找大於基準數的數,並交換,直到兩個相遇,5,1,4,2,26,9,5,7,52,21    現在右邊找到的是2,左邊到2的時候,還沒有找到比基準數大的數,那麼就將基準數和2進行交換  2,1,4,5,26,9,5,7,52,21 這個時候,基準數左邊的數,都是小於它的,右邊的數都是大於等於它的。我們可以得到兩個數列2,1,4       26,9,5,7,52,21  然後分別對這兩個數列進行上面順序的排序第一次排序結果:基準數 5 結果:2,1,4,5,26,9,5,7,52,21  左邊子數列 2,1,4  右邊子數列  26,9,5,7,52,21
第二次排序:比如 2,1,4  我們以2為基準數,右到左  找到1  左到右 到了1的角標也沒找到,就將基準數和1進行交換1,2,4    得到兩個數列, 1   4  這兩個數列都只有一個數,不需要排序了,左邊數列的排序就完成了,可以得到  1,2,4,5,26,9,5,7,52,21  第二次排序結果:基準數 2 結果:1,2,4,5,26,9,5,7,52,21  左邊子數列 1  右邊子數列 4
第三次排序:左邊數列 1 不需要排序第三次排序結果:基準數  1  結果:1,2,4,5,26,9,5,7,52,21  左邊子數列 無   右邊子數列 無第四次排序:右邊數列 4  不需要排序第四次排序結果:基準數 4   結果:1,2,4,5,26,9,5,7,52,21  左邊子數列 無   右邊子數列  無第五次排序:再對第一次排序結果的右邊的數列進行排序  26,9,5,7,52,21以26為基準數 , 右到左  21  左到右 52 交換21和52  得到26,9,5,7,21,52它們還沒相遇,繼續以26為基準數,右到左,21   左到右 沒有  交換 26和21 得到21,9,5,7,26,52現在26左邊的都小於它,右邊的都大於它,第五次排序結果:基準數 26  結果:1,2,4,5,21,9,5,7,26,52   左邊子數列 21,9,5,7  右邊子數列 52第六次排序:對第五次排序的左邊子數列進行排序我們對21,9,5,7這個數列進行排序以21為基準,右到左 7  左到右 沒有 交換21 和7 得到7,9,5,21 基準數21右邊沒有 左邊7,9,5數列都小於它第六次排序結果:基準數 21  結果:1,2,4,5,7,9,5,7,21,26,52  左邊子數列 7,9,5  右邊子數列 無
第七次排序:對第六次排序的左邊子數列進行排序對7,9,5進行排序  以7為基準數 ,右到左 5  左到右 9 交換5和9  得到7,5,9繼續右到左 5  左到右 沒有 交換基準數和5  得到5,7, 9 這時,基準數左邊右邊都排序完成 第七次排序結果:基準數  7 結果:1,2,4,5,5,7,9,21,26,52  左邊子數列 5    右邊子數列 9第八次排序:左邊數列 5第八次排序結果:基準數 5  結果:1,2,4,5,5,7,9,21,26,52  左邊子數列 無   右邊子數列 無第九次排序:右邊數列 9第九次排序結果:基準數 9  結果:1,2,4,5,5,7,9,21,26,52  左邊子數列  無   右邊子數列 無第十次排序:我們還有個第一次排序結果的右邊子數列沒有排序基準數為26時,左邊排序完成,剩下右邊的數列 52 進行排序第十次排序結果:基準數 52 結果:1,2,4,5,5,7,9,21,26,52  左邊子數列 無   右邊子數列  無此時,當所有排序都完成,得到了 1,2,4,5,5,7,9,21,26,52快速排序之所以比氣泡排序快,是因為他的交換都是跳躍式的,而不像冒泡只能對相鄰的進行排序。因此總的比較和交換的次數就少了,速度自然提高了。即使是最差的情況,也就是說還是相鄰的進行交換,它的時間複雜度也是O(n * n)

演算法實現:
private void fastSort(int left,int right){
    int temp;//儲存的是基準數,用於基準數和左右相遇座標點的交換
    int t;//用來輔助交換的數
    int i;
    int j;
    if (left > right){
        return;//說明該數列不需要排序
    }
    temp = a[left];//初始化基準數
    i = left;
    j = right;
    while (i != j){
        //如果兩個角標還沒有相遇
        //先從右到左,找第一個小於基準數的數
        while (a[j] >= temp && i < j){
            j--;
        }
        //從左到右,找第一個大於基準數的數
        while (a[i] <= temp && i < j){
            i++;
        }
        //現在找到的right和left角標,就進行交換
        if (i < j){
           t = a[i];
           a[i] = a[j];
            a[j] = t;
        }
    }
    //當i==j的時候,說明相遇了,需要將基準數和當前相遇座標點的數進行交換。
    a[left] = a[i];
    a[i] = temp;
    // 到這裡完成了一次基準數排序,現在需要遞迴對子數列進行排序
    Log.i("hero","當前基準數---"+temp+"----當次排序---結果---"+ Arrays.toString(a));
    fastSort(left,i-1);//對基準數左邊子數列的進行排序
    fastSort(i+1,right);//對基準數右邊子數列的進行排序
    return;
}
呼叫程式碼:
int[] a = {5,1,9,26,2,4,5,7,52,21};
 fastSort(0,a.length-1);
執行結果:<Image_2>