受限於「僅能使用一個輔助棧/隊列及少量變數」的條件下對棧/隊列排序,是經典面試題。本文提供兩種基於 LinkedList 的實作:雙棧選擇排序與單隊列選擇排序,並分析時間複雜度。
stackOne,stackTwo 為空。max,其餘推入「目標棧」。max 推回源棧(此為已排序區域底部)。public class StackSort {
private IntStack stackOne, stackTwo;
private int size;
private static final int START_ONE=1, START_TWO=2;
public StackSort(int[] arr) {
stackOne=new IntStack(); stackTwo=new IntStack();
for(int v:arr){ stackOne.push(v); size++; }
}
public int sort() {
int sizeOne=size, sizeTwo=0;
while (sizeOne!=1 && sizeTwo!=1) {
// 從 stackOne 找最大
int max = stackOne.pop(); sizeOne--;
while (sizeOne>0) {
int v = stackOne.pop();
if (v>max){ stackTwo.push(max); max=v; }
else stackTwo.push(v);
sizeOne--; sizeTwo++;
}
stackOne.push(max); // 最大值歸位
if (sizeTwo==1) return START_TWO;
// 從 stackTwo 找次大
max = stackTwo.pop(); sizeTwo--;
while (sizeTwo>0) {
int v = stackTwo.pop();
if (v>max){ stackOne.push(max); max=v; }
else stackOne.push(v);
sizeTwo--; sizeOne++;
}
stackTwo.push(max);
}
return (sizeOne>sizeTwo)? START_ONE : START_TWO;
}
public void printResult(int start) {
IntStack first = (start==START_ONE)?stackOne:stackTwo;
IntStack second = (start==START_ONE)?stackTwo:stackOne;
while (!first.empty() && !second.empty()) {
System.out.print(first.pop()+" "+second.pop()+" ");
}
if (!first.empty()) System.out.print(first.pop());
System.out.println();
}
}
queueOne 存放待排數據,目標隊列 queueTwo 為空。queueOne 依序 poll() 所有元素,記錄最大值 max,其餘 offer() 回 queueOne。max offer() 到 queueTwo(隊尾)。queueOne 為空。queueTwo 內元素由大到小排列(先進先出輸出即為降序)。public class QueueSort {
private IntQueue queueOne, queueTwo;
private int size;
public QueueSort(int[] arr) {
queueOne=new IntQueue(); queueTwo=new IntQueue();
for(int v:arr){ queueOne.offer(v); size++; }
}
public void sort() {
int remaining = size;
while (remaining > 0) {
int max = queueOne.poll();
int turn = remaining - 1;
while (turn > 0) {
int v = queueOne.poll();
if (v > max) { queueOne.offer(max); max = v; }
else queueOne.offer(v);
turn--;
}
queueTwo.offer(max);
remaining--;
}
}
public void printResult() {
while (!queueTwo.empty()) System.out.print(queueTwo.poll()+" ");
System.out.println();
}
}
// IntStack 同前
// IntQueue 基於 LinkedList 實作 Queue 介面
public class IntQueue {
private Queue<Integer> q = new LinkedList<>();
public void offer(int v) { q.offer(v); }
public int poll() { return q.poll(); }
public boolean empty() { return q.isEmpty(); }
}
棧排序利用「雙棧倒騰」模擬選擇排序,隊列排序利用「循環掃描+輔助隊列」同樣實現選擇排序。兩者皆為 O(n²),教學意義大於實用。實際開發中,將數據倒入 List 呼叫 Collections.sort() (TimSort, O(n log n)) 才是正道。