棧(LIFO)與隊列(FIFO)是最基礎的線性結構。本文提供基於數組的順序棧、循環隊列 C 實現,含初始化、入棧/出棧、入隊/出隊、判空、進制轉換演示、隨機測試等完整代碼。
#define MAXSIZE 20
typedef int SElemType;
typedef struct { SElemType data[MAXSIZE]; int top; } SqStack;
Status InitStack(SqStack* s) { s->top = -1; return 1; }
Status Push(SqStack* s, SElemType e) {
if (s->top == MAXSIZE-1) return 0; // 滿
s->data[++s->top] = e; return 1;
}
Status Pop(SqStack* s, SElemType* e) {
if (s->top == -1) return 0; // 空
*e = s->data[s->top--]; return 1;
}
void Conversion() {
SqStack* s = malloc(sizeof(SqStack)); InitStack(s);
int N; scanf("%d", &N);
while (N) { Push(s, N % 8); N /= 8; }
int e; while (s->top != -1) { Pop(s, &e); printf("%d", e); }
free(s);
}
利用棧「後進先出」特性,自動反轉餘數序列,輸出正確八進制數。
typedef struct { QElemType Data[MAXSIZE]; int front, rear; } XHQueue;
void InitQueue(XHQueue* Q) { Q->front = Q->rear = 0; }
Status EnQueue(XHQueue* Q, QElemType e) {
if ((Q->rear + 1) % MAXSIZE == Q->front) return 0; // 滿:留一空位區分空滿
Q->Data[Q->rear] = e; Q->rear = (Q->rear + 1) % MAXSIZE; return 1;
}
Status DeQueue(XHQueue* Q, QElemType* e) {
if (Q->front == Q->rear) return 0; // 空
*e = Q->Data[Q->front]; Q->front = (Q->front + 1) % MAXSIZE; return 1;
}
Status IsEmpty(XHQueue* Q) { return Q->front == Q->rear; }
front 指向隊頭元素,rear 指向隊尾下一位置。(rear+1)%MAXSIZE == front 判滿,犧牲一個存儲單元換取 O(1) 判空/判滿,避免數據搬移。
int main() {
XHQueue* Q = malloc(sizeof(XHQueue)); InitQueue(Q);
EnQueue(Q, 2); EnQueue(Q, 0); EnQueue(Q, 1); EnQueue(Q, 5);
int Re; while (!IsEmpty(Q)) { DeQueue(Q, &Re); printf("%d", Re); }
free(Q); return 0;
}
輸出:2015,驗證先進先出特性。
realloc),切勿忽略。Pop/DeQueue 需雙重指針或輸出參數指針,調用時 &val。srand(time(NULL)) 僅調用一次,放在程序開頭,避免同秒內重複序列。malloc 分配的結構體指針,用完必須 free。順序棧適合「逆序輸出、遞歸消除、表達式求值」;循環隊列適合「緩衝區、任務調度、BFS」。理解「用空間換時間」(留一空位判滿)、「模運算實現循環」兩大技巧,是掌握線性結構的關鍵。