栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。不含任何元素的栈称为空栈,栈又称为后进先出的线性表。压入push和弹出pop!插入是增加数据,弹出是删除数据,这些操作只能从栈顶即最低地址作为约束的接口界面入手操作
栈的分类:顺序栈,链式栈,下面代码为顺序栈
栈的大小:可配置
#pragma once
#include <stdio.h>
#include <assert.h>
#include <string.h>
typedef char DataType;
#define MAX_SIZE 10
typedef struct Stack{
DataType _array[MAX_SIZE];
int _size;
}Stack;
void StackInit(Stack* s);
void StackPush(Stack* s, DataType data);
void StackPop(Stack* s);
DataType StackTop(Stack* s);
int StackSize(Stack* s);
int StackEmpty(Stack* s);
void StackInit(Stack* s){
assert(s);
s->_size = 0;
}
void StackPush(Stack* s, DataType data){
assert(s);
if (s->_size == MAX_SIZE)
return;
s->_array[s->_size++] = data;
}
void StackPop(Stack* s){
assert(s);
if (StackEmpty(s)){
return;
}
s->_size--;
}
DataType StackTop(Stack* s){
assert(s);
return s->_array[s->_size - 1];
}
int StackSize(Stack* s){
assert(s);
return s->_size;
}
int StackEmpty(Stack* s){
assert(s);
return 0 == s->_size;
}
void TestStack(){
Stack s;
StackInit(&s);
StackPush(&s, 1);
StackPush(&s, 2);
StackPush(&s, 3);
StackPush(&s, 4);
StackPush(&s, 5);
StackPush(&s, 6);
printf("size = %d\n", StackSize(&s));
printf("Top = %d\n", StackTop(&s));
printf("Empty = %d\n", StackEmpty(&s));
StackPush(&s, 7);
StackPush(&s, 8);
StackPush(&s, 9);
StackPush(&s, 10);
printf("size = %d\n", StackSize(&s));
printf("Top = %d\n", StackTop(&s));
printf("Empty = %d\n", StackEmpty(&s));
StackPush(&s, 0);
printf("size = %d\n", StackSize(&s));
printf("Top = %d\n", StackTop(&s));
printf("Empty = %d\n", StackEmpty(&s));
StackPop(&s);
StackPop(&s);
StackPop(&s);
printf("size = %d\n", StackSize(&s));
printf("Top = %d\n", StackTop(&s));
printf("Empty = %d\n", StackEmpty(&s));
}
//栈的应用题
int IsBracket(char ch){
if ('(' == ch || ')' == ch ||
'[' == ch || ']' == ch ||
'{' == ch || '}' == ch)
return 1;
return 0;
}
int MatchBrackets(const char* pStr){
int i = 0;
int size = strlen(pStr);
Stack s;
StackInit(&s);
for (; i < size; ++i){
if (!IsBracket(pStr[i])){
continue;
}
else{
if ('(' == pStr[i] || '[' == pStr[i] || '{' == pStr[i]){
StackPush(&s, pStr[i]);
}
else{
char ch;
if (StackEmpty(&s)){
printf("右多\n");
return 0;
}
ch = StackTop(&s);
if ('(' == ch && ')' == pStr[i] ||
'[' == ch && ']' == pStr[i] ||
'{' == ch && '}' == pStr[i]){
StackPop(&s);
}
else{
printf("不匹配\n");
return 0;
}
}
}
}
if (!StackEmpty(&s)){
printf("左多\n");
return 0;
}
else{
printf("匹配成功\n");
return 1;
}
}
void Test(){
char a1[] = "(())abc{[(])}";
char a2[] = "(()))abc{[]}";
char a3[] = "((())abc{[]}";
char a4[] = "(())abc{[()]}";
printf("a1 = %d\n\n", MatchBrackets(a1));
printf("a2 = %d\n\n", MatchBrackets(a2));
printf("a3 = %d\n\n", MatchBrackets(a3));
printf("a4 = %d\n\n", MatchBrackets(a4));
}
int main(){
//TestStack();
Test();
return 0;
}
栈的常见考题:
带头节点的双向链表:
https://blog.csdn.net/Romantic_C/article/details/79991268
带头节点的单链表:
https://blog.csdn.net/Romantic_C/article/details/79919836
链表面试题:
https://blog.csdn.net/Romantic_C/article/details/81395660