1. 程式人生 > >棧操作實現與應用

棧操作實現與應用

棧,後進先出(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);
#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;
}

應用1:    使用順序棧實現檢測括號匹配問題
#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;
}
應用2:    走出迷宮
#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;
}