棧操作實現與應用
阿新 • • 發佈:2019-01-09
棧,後進先出(LILO) 只允許在一端(棧頂)進行入棧和出棧的操作,另一端為棧底 使用順序表實現
順序棧的操作實現
順序棧的操作實現
#pragma once #include<stdio.h> #include<assert.h> #include<windows.h> #include<Windows.h> typedef struct Position{ int x; int y; }Postion;//迷宮位置 //typedef Position SDataType; typedef int SDataType; #define MAX_SIZE (100) typedef struct Stack{ SDataType arr[MAX_SIZE];//size int top;//表示有效資料個數;表示當前可用位置 }Stack; //初始化 void StackInit(Stack *pS); //入棧 void StackPush(Stack *pS, SDataType data); //出棧 void StackPop(Stack *pS); //返回棧頂元素 SDataType StackTop(Stack *pS); //判斷是否為空,1表示空,0表示非空 int StackIsEmpty(Stack *pS); //返回棧元素個數 int StackSize(Stack *pS); //棧拷貝 void StackCopy(Stack *pDest, Stack *pSrc);
應用1: 使用順序棧實現檢測括號匹配問題#include "Stack.h" //初始化 void StackInit(Stack *pS) { assert(pS); pS->top = 0; } //入棧 void StackPush(Stack *pS, SDataType data) { assert(pS); assert(pS->top < MAX_SIZE); pS->arr[pS->top++] = data; } //出棧 void StackPop(Stack *pS) { assert(pS); assert(pS->top > 0); pS->top--; } //返回棧頂元素 SDataType StackTop(Stack *pS) { assert(pS); assert(pS->top > 0); return pS->arr[pS->top - 1]; } //判斷是否為空,1表示空,0表示非空 int StackIsEmpty(Stack *pS) { return pS->top == 0 ? 1 : 0; } //返回棧元素個數 int StackSize(Stack *pS) { return pS->top; } //棧拷貝 void StackCopy(Stack *pDest, Stack *pSrc) { pDest->top = pSrc->top; memcpy(pDest->arr, pSrc->arr, sizeof(SDataType)*pSrc->top); } void print(Stack *pS) { for (int i = 0; i < pS->top; i++){ printf("%d ", pS->arr[i]); } printf("\n"); } int main() { Stack stack; StackInit(&stack); StackPush(&stack, 1); StackPush(&stack, 2); StackPush(&stack, 3); StackPush(&stack, 4); print(&stack); StackPop(&stack); StackPop(&stack); print(&stack); printf("%d\n", StackTop(&stack)); Stack stack1; StackInit(&stack1); StackCopy(&stack1, &stack); print(&stack1); system("pause"); return 0; }
應用2: 走出迷宮#include "Stack.h" //括號是否匹配 void IsBracketMatch(const char *str) { const char *str1 = str; Stack stack; char ch; StackInit(&stack); while (*str1){ switch (*str1){ case '(': case '{': case '[': StackPush(&stack, *str1); break; case ')': case '}': case ']': if (StackIsEmpty(&stack)){//1為空 printf("右括號比左括號多\n"); return; } ch = StackTop(&stack); StackPop(&stack); if (!((ch == '(' && *str1 == ')') || (ch == '{' && *str1 == '}') || \ (ch == '[' && *str1 == ']'))){ printf("左右括號不匹配\n"); return; } break; } str1++; } if (!StackIsEmpty(&stack)){ printf("左括號比右括號多\n"); return; } printf("左右括號匹配\n"); } int main() { IsBracketMatch("(())abc{[(])}"); IsBracketMatch("(()))abc{[]}"); IsBracketMatch("(()()abc{[]}"); IsBracketMatch("(())abc{[]()}"); system("pause"); return 0; }
#include "Stack.h"
//使用棧與遞迴實現迷宮
#define ROWS 6
#define COLS 6
//判斷是否可走
int IsAccess(int maze[ROWS][COLS], Position pos)
{
if (pos.y < 0 || pos.y >= ROWS) {
return 0;
}
if (pos.x < 0 || pos.x >= COLS) {
return 0;
}
return maze[pos.y][pos.x] == 1 ? 1 : 0;
}
//是否找到出口
int IsExit(Position pos)
{
return pos.x == COLS - 1 ? 1 : 0;
}
void PrintMaze(int maze[ROWS][COLS])
{
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%d ", maze[i][j]);
}
printf("\n");
}
}
void GoMaze(int maze[ROWS][COLS], Position entry)
{
Position pos = entry; // 當前所處位置
Position nextPos; // 要嘗試的位置
Stack stack;
StackInit(&stack);
while (1) {
maze[pos.y][pos.x] = 2; // 表示這個路來過
system("cls");
PrintMaze(maze);
Sleep(500);
if (IsExit(pos)) {
// 回溯
pos = StackTop(&stack);
StackPop(&stack);
maze[pos.y][pos.x] = 3;
system("cls");
printf("出口\n");
PrintMaze(maze);
Sleep(2000);
continue;
}
// 左 -> 上 -> 右 -> 下
nextPos = pos;
nextPos.x -= 1;
if (IsAccess(maze, nextPos)) {
StackPush(&stack, pos);
pos = nextPos;
continue;
}
nextPos = pos;
nextPos.y -= 1;
if (IsAccess(maze, nextPos)) {
StackPush(&stack, pos);
pos = nextPos;
continue;
}
nextPos = pos;
nextPos.x += 1;
if (IsAccess(maze, nextPos)) {
StackPush(&stack, pos);
pos = nextPos;
continue;
}
nextPos = pos;
nextPos.y += 1;
if (IsAccess(maze, nextPos)) {
StackPush(&stack, pos);
pos = nextPos;
continue;
}
// 回溯
if (StackIsEmpty(&stack)) {
printf("迷宮探索結束\n");
return;
}
pos = StackTop(&stack);
StackPop(&stack);
}
}
int main()
{
int maze[ROWS][COLS] = {
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 1 },
{ 0, 0, 1, 0, 1, 0 },
{ 0, 0, 1, 1, 1, 0 },
{ 0, 0, 1, 0, 1, 1 },
{ 0, 0, 1, 0, 0, 0 }
};
Position entry = { 2, 5 };
GoMaze(maze, entry);
PrintMaze(maze);
system("pause");
return 0;
}
找出走出迷宮最短路徑#include "Stack.h"
//使用棧與遞迴實現迷宮
#define ROWS 6
#define COLS 6
//判斷是否可走
int IsAccess(int maze[ROWS][COLS], Position pos)
{
if (pos.y < 0 || pos.y >= ROWS) {
return 0;
}
if (pos.x < 0 || pos.x >= COLS) {
return 0;
}
return maze[pos.y][pos.x] == 1 ? 1 : 0;
}
//是否找到出口
int IsExit(Position pos)
{
return (pos.x == COLS - 1) ? 1 : 0;
}
void PrintMaze(int maze[ROWS][COLS])
{
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%d ", maze[i][j]);
}
printf("\n");
}
}
void GoMazeRecursion(Stack *pPath, Stack *pShort, int maze[][COLS], Position pos)
{//1代表路,0代表牆
maze[pos.y][pos.x] = 2; //表示這個路來過
StackPush(pPath, pos);
Position nextPos;
if (IsExit(pos)){
if (StackIsEmpty(pShort) || StackSize(pPath) < StackSize(pShort)){
//找到新的最短路徑
StackCopy(pShort, pPath);
}
maze[pos.y][pos.x] = 1;
StackPop(pPath);
return;
}
nextPos = pos;// 左 -> 上 -> 右 -> 下
nextPos.x -= 1;
if (IsAccess(maze, nextPos)) {
GoMazeRecursion(pPath, pShort, maze, nextPos);
}
nextPos = pos;
nextPos.y -= 1;
if (IsAccess(maze, nextPos)) {
GoMazeRecursion(pPath, pShort, maze, nextPos);
}
nextPos = pos;
nextPos.x += 1;
if (IsAccess(maze, nextPos)) {
GoMazeRecursion(pPath, pShort, maze, nextPos);
}
nextPos = pos;
nextPos.y += 1;
if (IsAccess(maze, nextPos)) {
GoMazeRecursion(pPath, pShort, maze, nextPos);
}
StackPop(pPath);
maze[pos.y][pos.x] = 1;
}
int main()
{
Stack pathStack;
Stack shortPathStack;
int maze[ROWS][COLS] = {
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 1 },
{ 0, 0, 1, 0, 1, 0 },
{ 0, 0, 1, 1, 1, 0 },
{ 0, 0, 1, 0, 1, 1 },
{ 0, 0, 1, 0, 0, 0 }
};
Position entry = { 2, 5 };
StackInit(&pathStack);
StackInit(&shortPathStack);
GoMazeRecursion(&pathStack, &shortPathStack, maze, entry);
while (!StackIsEmpty(&shortPathStack)){
Position pos = StackTop(&shortPathStack);
StackPop(&shortPathStack);
maze[pos.y][pos.x] = 4;
}
PrintMaze(maze);
system("pause");
return 0;
}