-
栈的定义
栈是一种特殊的线性表。其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
栈分顺序栈和链式栈,不过通常使用的是顺序栈。下面介绍顺序栈。
-
栈的存储方式
typedef struct Stack
{
SDataType array[MAX_SIZE];
int top;
} Stack;
-
栈的基本运算
#pragma once
#include <assert.h>
#define MAX_SIZE (100)
typedef int SDataType;
typedef struct Stack
{
SDataType array[MAX_SIZE];
int top;
} Stack;
//初始化
void StackInit(Stack *pS)
{
pS->top = 0;
}
//销毁
void StackDestroy(Stack *pS)
{
pS->top = 0;
}
//压栈
void StackPush(Stack *pS, SDataType data)
{
assert(pS->top < MAX_SIZE);
pS->array[pS->top++] = data;
}
//出栈
void StackPop(Stack *pS)
{
assert(pS->top > 0);
pS->top--;
}
//返回栈顶元素
SDataType StackTop(const Stack *pS)
{
assert(pS->top > 0);
return pS->array[pS->top - 1];
}
//站内元素的个数
int StackSize(const Stack *pS)
{
return pS->top;
}
//判断栈是否为空
int StackEmpty(const Stack *pS)
{
return pS->top == 0 ? 1 : 0;
}
栈的应用
-
括号匹配问题
#define _CRT_SECURE_NO_DEPRECATE 1
#include "stack.h"
void MatchBrackets(const char* p)
{
Stack stack;
StackInit(&stack);
while (*p!='\0')
{
switch (*p)
{
case '(':
case '{':
case '[':
StackPush(&stack,*p);
break;
case ')':
case '}':
case ']':
if (StackEmpty(&stack))
{
printf("右括号多\n");
return;
}
char top = StackTop(&stack);
StackPop(&stack);
if (!((top == '(' && *p == ')') ||
(top == '[' && *p == ']' )||
(top == '{' && *p == '}' )))
{
printf("左右括号不匹配\n");
return;
}
break;
default:
break;
}
p++;
}
if (!StackEmpty(&stack))
{
printf("左括号多\n");
}
else
{
printf("左右括号匹配\n");
}
}
int main()
{
char a[] = "(())abc{[(])}"; // 左右括号次序匹配不正确
char b[] = "(()))abc{[]}"; // 右括号多于左括号
char c[] = "(()()abc{[]}"; // 左括号多于右括号
char d[] = "(())abc{[]()}";
MatchBrackets(a);
MatchBrackets(b);
MatchBrackets(c);
MatchBrackets(d);
return 0;
}
-
逆波兰表达式
#include "stack.h"
typedef enum
{
NUMBER,
OPERATE
}Type;
typedef enum
{
ADD,
SUB,
DIV,
MUL,
NOUSED
}OP;
typedef struct
{
Type type;
int number;
OP operate;
}Item;
Item array[] =
{
{
NUMBER,
125,
NOUSED
},
{
NUMBER,
145,
NOUSED
},
{
OPERATE,
-1,
SUB
}
};
void RPN(Item array[], int size)
{
Stack stack;
StackInit(&stack);
for (int i = 0; i < size; i++)
{
if (array[i].type == NUMBER)
{
StackPush(&stack, array[i].number);
}
else
{
int n1 = StackTop(&stack);
StackPop(&stack);
int n2 = StackTop(&stack);
StackPop(&stack);
int result;
switch (array[i].operate)
{
case ADD:
result = n1 + n2;
break;
case SUB:
result = n2 - n1;
break;
case MUL:
result = n1 * n2;
break;
case DIV:
result = n2 / n1;
break;
}
StackPush(&stack, result);
}
}
assert(StackSize(&stack) == 1);
printf("%d\n", StackTop(&stack));
}
int main()
{
int size = sizeof(array) / sizeof(array[0]);
RPN(array, size);
return 0;
}
-
迷宫
- 简单迷宫
#define _CRT_SECURE_NO_DEPRECATE 1
#include "Windows.h"
#include "stdio.h"
typedef struct
{
int x;
int y;
}position;
#include "stack.h"
#define ROWS (6)
#define COLS (6)
int g_maze[ROWS][COLS] = {
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 0 },
{ 0, 0, 1, 0, 1, 1 },
{ 0, 0, 1, 0, 0, 0 }
};
void PrintMaze()
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
if (g_maze[i][j]==1)
{
printf(" ");
}
else if (g_maze[i][j]==0)
{
printf("■");
}
else if (g_maze[i][j] == 2) {
printf("⊙");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
int IsExit(position pos)
{
if (pos.y==COLS-1)
{
return 1;
}
else
{
return 0;
}
}
int CanPass(position pos)
{
// 先判断是否越界
if (pos.x < 0 || pos.x >= ROWS) {
return 0;
}
if (pos.y < 0 || pos.y >= COLS) {
return 0;
}
// 再判断是否是路
if (g_maze[pos.x][pos.y] == 1)
{
return 1;
}
else {
return 0;
}
}
void GoMaze(position entry)
{
Stack stack;
StackInit(&stack);
position pos = entry;
position nextpos;
while (1)
{
g_maze[pos.x][pos.y] = 2;//走过的路标记为2
system("cls");
PrintMaze();
Sleep(300);
StackPush(&stack, pos);
if (IsExit(pos))
{
printf("找到出口\n");
return;
}
nextpos = pos;
nextpos.y--;
if (CanPass(nextpos))
{
pos = nextpos;
continue;
}
nextpos = pos;
nextpos.x -= 1;
if (CanPass(nextpos)) {
pos = nextpos;
continue;
}
nextpos = pos;
nextpos.y += 1;
if (CanPass(nextpos)) {
pos = nextpos;
continue;
}
nextpos = pos;
nextpos.x += 1;
if (CanPass(nextpos)) {
pos = nextpos;
continue;
}
g_maze[pos.x][pos.y] = 3;
pos = StackTop(&stack);
StackPop(&stack);
if (StackEmpty(&stack))
{
printf("结束\n");
return;
}
pos = StackTop(&stack);
StackPop(&stack);
}
}
int main()
{
position entry = { 5, 2 };
GoMaze(entry);
return 0;
}
- 多通路迷宫:通路间不带环
#define _CRT_SECURE_NO_DEPRECATE 1
#include "Windows.h"
#include "stdio.h"
typedef struct
{
int x;
int y;
} position;
#define ROWS (6)
#define COLS (6)
#include "stack.h"
int g_maze[ROWS][COLS] = {
{ 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 1 },
{ 0, 1, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 1 },
{ 0, 1, 0, 0, 0, 0 }
};
void PrintMaze()
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
if (g_maze[i][j] == 1)
{
printf(" ");
}
else if (g_maze[i][j] == 0)
{
printf("■");
}
else if (g_maze[i][j] == 2) {
printf("⊙");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
int IsExit(position pos)
{
if (pos.y == COLS-1)
{
return 1;
}
else
{
return 0;
}
}
int CanPass(position pos)
{
// 先判断是否越界
if (pos.x < 0 || pos.x >= ROWS) {
return 0;
}
if (pos.y < 0 || pos.y >= COLS) {
return 0;
}
// 再判断是否是路
if (g_maze[pos.x][pos.y] == 1) {
return 1;
}
else {
return 0;
}
}
void GoMaze(position entry)
{
Stack stack;
StackInit(&stack);
position pos = entry;
position nextpos;
while (1)
{
g_maze[pos.x][pos.y] = 2;
system("cls");
PrintMaze();
Sleep(100);
StackPush(&stack, pos);
if (IsExit(pos))
{
printf("找到出口\n");
g_maze[pos.x][pos.y] = 0;
goto BACK;
}
nextpos = pos;
nextpos.y--;
if (CanPass(nextpos))
{
pos = nextpos;
continue;
}
nextpos = pos;
nextpos.x -= 1;
if (CanPass(nextpos))
{
pos = nextpos;
continue;
}
nextpos = pos;
nextpos.y += 1;
if (CanPass(nextpos))
{
pos = nextpos;
continue;
}
nextpos = pos;
nextpos.x += 1;
if (CanPass(nextpos))
{
pos = nextpos;
continue;
}
BACK:
pos = StackTop(&stack);
StackPop(&stack);
if (StackEmpty(&stack))
{
printf("结束\n");
return;
}
pos = StackTop(&stack);
StackPop(&stack);
}
}
int main()
{
position entry = { 5, 1 };
GoMaze(entry);
return 0;
}
- 多通路迷宫:通路带环
#define _CRT_SECURE_NO_DEPRECATE 1
#include "Windows.h"
#include "stdio.h"
typedef struct
{
int x;
int y;
} position;
#define ROWS (6)
#define COLS (6)
#include "stack.h"
int g_maze[ROWS][COLS] = {
{ 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 0, 0 },
{ 0, 1, 0, 1, 0, 0 },
{ 0, 1, 0, 1, 0, 0 },
{ 0, 1, 1, 1, 1, 1 },
{ 0, 1, 0, 0, 0, 0 }
};
void PrintMaze()
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
if (g_maze[i][j] == 1)
{
printf(" ");
}
else if (g_maze[i][j] == 0)
{
printf("■");
}
else if (g_maze[i][j] == 2) {
printf("⊙");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
int IsExit(position pos)
{
if (pos.y == COLS - 1)
{
return 1;
}
else
{
return 0;
}
}
int CanPass(position pos)
{
// 先判断是否越界
if (pos.x < 0 || pos.x >= ROWS) {
return 0;
}
if (pos.y < 0 || pos.y >= COLS) {
return 0;
}
// 再判断是否是路
if (g_maze[pos.x][pos.y] == 1) {
return 1;
}
else {
return 0;
}
}
void GoMazeR(position pos)
{
position nextpos;
g_maze[pos.x][pos.y] = 2;
system("cls");
PrintMaze();
Sleep(300);
if (IsExit(pos))
{
printf("找到出口\n");
g_maze[pos.x][pos.y] = 1;
return;
}
nextpos = pos;
nextpos.y-=1;
if (CanPass(nextpos))
{
GoMazeR(nextpos);
}
nextpos = pos;
nextpos.x -= 1;
if (CanPass(nextpos))
{
GoMazeR(nextpos);
}
nextpos = pos;
nextpos.y += 1;
if (CanPass(nextpos))
{
GoMazeR(nextpos);
}
nextpos = pos;
nextpos.x += 1;
if (CanPass(nextpos))
{
GoMazeR(nextpos);
}
g_maze[pos.x][pos.y] = 1;
}
int main()
{
position entry = { 5, 1 };
GoMazeR(entry);
return 0;
}