栈是后进先出线性表,顺序栈用连续的地址空间存储栈的元素,基本操作:出栈、入栈、判空、元素个数等,操作比较简单。
top == base,是栈空标志
#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 10
#define STACKINCREMENT 10
// 顺序栈实现
// todo: 数制转换、行编辑、括号匹配、迷宫求解、表达式求值
typedef int SElemType;
typedef bool Status;
typedef struct {
SElemType* base;
SElemType* top;
int stackSize;
}SqStack;
void initStack(SqStack &S) {
S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
S.top = S.base;
S.stackSize = STACK_INIT_SIZE;
}
Status pop(SqStack &S, SElemType &e) {
if(S.top == S.base) // 栈空
return false;
S.top--;
e = *(S.top);
// S.stackSize--; // stackSize是栈空间大小,不是栈内元素多少
}
Status empty(SqStack &S) {
return S.top == S.base;
}
int size(SqStack &S) {
return S.top - S.base;
}
Status push(SqStack &S, SElemType e) {
if(S.top-S.base == S.stackSize) {
printf("stack full, size: %d\n", size(S));
S.base = (SElemType*)realloc(S.base, (S.stackSize + STACKINCREMENT) * sizeof(SElemType));
S.top = S.base + S.stackSize;
S.stackSize += STACKINCREMENT;
}
*S.top++ = e;
// S.stackSize++; // stackSize是栈空间大小,不是栈内元素多少
return true;
}
SElemType top(SqStack &S) {
if(S.top == S.base)
return -1; // 栈空,返回异常值
return *(S.top-1);
}
Status destroy(SqStack &S) {
free(S.base);
S.base = NULL;
S.top = NULL;
S.stackSize = 0;
}
Status clear(SqStack &S) {
S.top = S.base;
S.stackSize = 0;
printf("clear stack\n");
}
void print(SqStack &S) {
printf("output stack: \t");
SElemType *p = S.top-1;
while (p>=S.base) {
printf("%d\t", *p--);
}
printf("\n");
}
/*
* val: 要转换的非负十进制数
* d:目标进制
* */
void NumTrans(SqStack &S, SElemType val, int d) {
while (val/d) {
SElemType tmp = val % d;
push(S, tmp);
val = val/d;
}
push(S, val);
}
/* 数制转换
* 输入:非负十进制整数
* 输出:等价的八进制数
*/
void NumeTransDemo() {
int n=100;
SqStack s;
initStack(s);
NumTrans(s, n, 2); // 转换二进制
print(s);
clear(s);
NumTrans(s, n, 8); // 转换十进制
print(s);
}
void basicOperationDemo() {
printf("basic operation demo\n");
SqStack s;
initStack(s);
push(s, 1);
push(s, 2);
push(s, 3);
print(s);
printf("size: %d\n", size(s));
printf("top: %d\n", top(s));
SElemType e;
pop(s, e);
printf("after pop\n");
printf("pop :%d\n", e);
printf("size: %d\n", size(s));
print(s);
pop(s, e);
printf("empty: %d\n", empty(s));
pop(s, e);
printf("empty: %d\n", empty(s));
push(s, 1);
push(s, 2);
push(s, 3);
clear(s);
printf("empty: %d\n", empty(s));
push(s, 1);
push(s, 2);
push(s, 3);
for(int i=0; i<10; i++)
push(s, i);
print(s);
destroy(s);
}
int main() {
basicOperationDemo();
NumeTransDemo();
return 0;
}