3.9 排序三個整數

「把幾個數字由小到大排好」是寫程式非常常見的需求。你可能想:這不是要等學會陣列、迴圈才做得到嗎?其實只用目前學過的比較和 if,就能把 3 個整數排好順序。這一節就帶你動手做一次,順便認識一個超好用的小技巧——變數交換

熱身:找出三個數中最大的

先從簡單的開始:讀入三個整數 abc,只找出最大值。做法像「打擂台」——先讓 a 上台當擂主,再讓 bc 輪流來挑戰,誰比較大誰就當新擂主:

int a, b, c;
cin >> a >> b >> c;

int biggest = a;          // 先假設 a 最大(a 當擂主)
if (b > biggest) {
    biggest = b;          // b 更大,換 b 當擂主
}
if (c > biggest) {
    biggest = c;          // c 更大,換 c 當擂主
}

cout << biggest << endl;  // biggest 就是三者中最大的

只要兩個 if,就能從三個數裡挑出最大的。同樣的道理,把 > 改成 < 就能找最小值

小技巧:交換兩個變數的值

要排序,就得在發現「順序不對」時把兩個變數的值對調。但直接這樣寫是錯的:

// ✗ 錯誤:沒有暫存,a 的值被蓋掉了
a = b;
b = a;   // 這時 a 已經變成 b,兩個都會是 b 的值

正確做法是先用一個暫存變數把其中一個值存起來:

// ✓ 正確:用暫存變數 t 保住 a 的值
int t = a;   // 先把 a 存進 t
a = b;       // 把 b 的值放進 a
b = t;       // 再把原本 a 的值(存在 t)放進 b

這個「借一個暫存變數來交換」的技巧,之後在排序、演算法裡會不斷用到。

把三個數由小到大排好

有了「比較」和「交換」,排序三個數只要三次比較就搞定:

int a, b, c;
cin >> a >> b >> c;

// 第 1 步:讓 a ≤ b(順序不對就交換 a、b)
if (a > b) {
    int t = a;
    a = b;
    b = t;
}
// 第 2 步:讓 a ≤ c,做完後 a 就是三者中最小的
if (a > c) {
    int t = a;
    a = c;
    c = t;
}
// 第 3 步:最後排好 b、c
if (b > c) {
    int t = b;
    b = c;
    c = t;
}

cout << a << " " << b << " " << c << endl;  // 由小到大

每個 if 裡的暫存變數 t 只在自己那對大括號內存在(還記得 3.8 的變數範圍嗎?),出了 { } 就消失,所以三段各自用 t 不會互相干擾。

為什麼三次就夠?

  • 前兩個 if 分別讓 abac 都小 → 做完後 a 一定是三者中最小的
  • 最小的已經歸位,剩下 bc 只要再比一次、大的往後放,三個就全部排好了。

(如果要由大到小,把三個 > 都改成 < 就行。)

動手試試看

先自己完成上面的「由小到大排序三個整數」。接著挑戰 三角形判斷(apcs201610p1)——它要你判斷三段長度能不能組成三角形、以及是銳角/直角/鈍角,而關鍵的第一步,就是先找出最長的一邊,正好用得上這一節學的技巧。