進制轉換中「輸出順序與計算順序相反」的特性,與棧的後進先出(LIFO)結構天然契合。本文提供基於順序棧的完整C語言實現,演示如何將十進制整數轉換為任意進制(2-36),並深度解析棧在逆序輸出場景中的核心價值。
void ConvertBase(SqStack *stack, unsigned int num, unsigned int base) {
if (!stack || base < 2 || base > 36) return;
// 特殊情況:0
if (num == 0) {
printf("0\n");
return;
}
// 核心邏輯:反覆除基取餘,餘數入棧
while (num > 0) {
int remainder = num % base;
Push(stack, remainder);
num /= base;
}
// 出棧輸出:自動實現逆序
printf("十進制 %u 轉 %u 進制結果: ", num, base);
int digit;
while (!IsEmpty(stack)) {
Pop(stack, &digit);
// 數字0-9輸出字符'0'-'9',10-35輸出'A'-'Z'
if (digit < 10) putchar('0' + digit);
else putchar('A' + digit - 10);
}
putchar('\n');
}
| 指標 | 複雜度 | 說明 |
|---|---|---|
| 時間 | O(logbaseN) | 每次除基運算減少一位 |
| 空間 | O(logbaseN) | 棧深度等於目標進制位數 |
| 棧最大深度 | 32(32位int二進制) | log₂(2³²) = 32 |
進制轉換是棧解決「正序處理、逆序輸出」問題的典型代表,同類場景包括:
對比結論:遞歸代碼更簡潔但隱含棧溢出風險(大數轉二進制時);顯式棧可控性更強,適合嵌入式/受限環境。
實戰優化建議
- 動態棧:用鏈表實現棧避免固定大小限制
- 位運算優化:基為2的冪次時用位掩碼和移位替代除模
- 緩衝區輸出:收集字符到緩衝區一次性輸出,減少I/O調用
- 錯誤處理:檢查基範圍(2-36),處理輸入為0的邊界情況
標準庫替代方案
棧實現進制轉換不僅是數據結構教學的經典案例,更展示了「數據結構服務於算法特性」的設計哲學。LIFO特性完美匹配逆序輸出需求,這種「問題特性與結構特性耦合」的思維,是成為優秀程序員的關鍵認知躍遷。