演算法(一)排序演算法(桶排序、氣泡排序、快速排序)
阿新 • • 發佈:2019-01-01
第一次排序:首先,找一個"基準數",比如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)
演算法實現:
第三次排序:左邊數列 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);
執行結果: