我们把类似于弹夹那种先进后出的数据结构称为栈,栈是限定仅在表尾进行插入和删除操作的线性表,我们把允许插入和删除的一端称为栈顶,另一端称为栈底,不含任何数据元素的栈称为空栈,栈又称后进后出的线性表,简称LIFO结构。
栈首先是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系,只不过它是一种特殊的线性表而已。
栈的特殊之处在于限制了这个线性表的插入和删除位置,它始终只在栈顶进行。这也就使得:栈底是固定的,最先进栈的只能在栈底。
栈的插入操作,叫做进栈;栈的删除操作叫做出栈。
#include#include #define STACK_MAX_SIZE 10 typedef struct CharStack { int top; int data[STACK_MAX_SIZE]; } *CharStackPtr; CharStackPtr charStackInit() { CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(CharStack)); resultPtr->top = -1; return resultPtr; } void outputStack(CharStackPtr paraStack) { for (int i = 0; i <= paraStack->top; i ++) { printf("%c ", paraStack->data[i]); } printf("rn"); } void push(CharStackPtr paraStackPtr, int paraValue) { if (paraStackPtr->top >= STACK_MAX_SIZE - 1) { printf("Cannot push element: stack full.rn"); return; } paraStackPtr->top ++; paraStackPtr->data[paraStackPtr->top] = paraValue; } char pop(CharStackPtr paraStackPtr) { if (paraStackPtr->top < 0) { printf("Cannot pop element: stack empty.rn"); return ' '; } paraStackPtr->top --; return paraStackPtr->data[paraStackPtr->top + 1]; } void pushPopTest() { printf("---- pushPopTest begins. ----rn"); CharStackPtr tempStack = charStackInit(); printf("After initialization, the stack is: "); outputStack(tempStack); for (char ch = 'a'; ch < 'm'; ch ++) { printf("Pushing %c.rn", ch); push(tempStack, ch); outputStack(tempStack); } for (int i = 0; i < 3; i ++) { ch = pop(tempStack); printf("Pop %c.rn", ch); outputStack(tempStack); } printf("---- pushPopTest ends. ----rn"); } void main() { pushPopTest(); }
是
括号匹配问题
#include
#include
#define STACK_MAX_SIZE 10
typedef struct CharStack {
int top;
int data[STACK_MAX_SIZE];
} *CharStackPtr;
CharStackPtr charStackInit() {
CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
resultPtr->top = -1;
return resultPtr;
}
void outputStack(CharStackPtr paraStack) {
for (int i = 0; i <= paraStack->top; i ++) {
printf("%c ", paraStack->data[i]);
}
printf("rn");
}
void push(CharStackPtr paraStackPtr, int paraValue) {
if (paraStackPtr->top >= STACK_MAX_SIZE - 1) {
printf("Cannot push element: stack full.rn");
return;
}
paraStackPtr->top ++;
paraStackPtr->data[paraStackPtr->top] = paraValue;
}
char pop(CharStackPtr paraStackPtr) {
if (paraStackPtr->top < 0) {
printf("Cannot pop element: stack empty.rn");
return ' ';
}
paraStackPtr->top --;
return paraStackPtr->data[paraStackPtr->top + 1];
}
void pushPopTest() {
printf("---- pushPopTest begins. ----rn");
CharStackPtr tempStack = charStackInit();
printf("After initialization, the stack is: ");
outputStack(tempStack);
for (char ch = 'a'; ch < 'm'; ch ++) {
printf("Pushing %c.rn", ch);
push(tempStack, ch);
outputStack(tempStack);
}
for (int i = 0; i < 3; i ++) {
ch = pop(tempStack);
printf("Pop %c.rn", ch);
outputStack(tempStack);
}
printf("---- pushPopTest ends. ----rn");
}
bool bracketMatching(char* paraString, int paraLength) {
CharStackPtr tempStack = charStackInit();
push(tempStack, '#');
char tempChar, tempPopedChar;
for (int i = 0; i < paraLength; i++) {
tempChar = paraString[i];
switch (tempChar) {
case '(':
case '[':
case '{':
push(tempStack, tempChar);
break;
case ')':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '(') {
return false;
}
break;
case ']':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '[') {
return false;
}
break;
case '}':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '{') {
return false;
}
break;
default:
break;
}
}
tempPopedChar = pop(tempStack);
if (tempPopedChar != '#') {
return true;
}
return true;
}
void bracketMatchingTest() {
char* tempExpression = "[2 + (1 - 3)] * 4";
bool tempMatch = bracketMatching(tempExpression, 17);
printf("Is the expression '%s' bracket matching? %d rn", tempExpression, tempMatch);
tempExpression = "( ) )";
tempMatch = bracketMatching(tempExpression, 6);
printf("Is the expression '%s' bracket matching? %d rn", tempExpression, tempMatch);
tempExpression = "()()(())";
tempMatch = bracketMatching(tempExpression, 8);
printf("Is the expression '%s' bracket matching? %d rn", tempExpression, tempMatch);
tempExpression = "({}[])";
tempMatch = bracketMatching(tempExpression, 6);
printf("Is the expression '%s' bracket matching? %d rn", tempExpression, tempMatch);
tempExpression = ")(";
tempMatch = bracketMatching(tempExpression, 2);
printf("Is the expression '%s' bracket matching? %d rn", tempExpression, tempMatch);
}
void main() {
// pushPopTest();
bracketMatchingTest();
}
表达式求值
#include#include #include #include #include using namespace std; stack num; stack op; void eval() { auto b = num.top(); num.pop(); auto a = num.top(); num.pop(); auto c = op.top(); op.pop(); int x; if (c == '+') x = a + b; else if (c == '-') x = a - b; else if (c == '*') x = a * b; else x = a / b; num.push(x); } int main() { unordered_map pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}}; string str; cin >> str; for (int i = 0; i < str.size(); i ++ ) { auto c = str[i]; if (isdigit(c)) { int x = 0, j = i; while (j < str.size() && isdigit(str[j])) x = x * 10 + str[j ++ ] - '0'; i = j - 1; num.push(x); } else if (c == '(') op.push(c); else if (c == ')') { while (op.top() != '(') eval(); op.pop(); } else { while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval(); op.push(c); } } while (op.size()) eval(); cout << num.top() << endl; return 0; }



