本文将数据结构学习中栈的应用举例的几个例子规整到本文当中,经测试均准确!
/*******************************************************************************
数据结构练习
--------------------------------------------------------------------------------
实 验 名: 栈的应用举例
实验说明: 数制转换
时 间: 2017-7-2
作 者: Elvan
*******************************************************************************/
#include
#include //malloc,realloc
#include //含有overflow
#include
using namespace std;
#define STACK_INIT_SIZE 100 //栈的初始空间大小
#define STACKINCREAMENT 10 //增加空间
/*数据类型定义*/
typedef int SElemType;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//----------------函数声明--------------
void InitStack(SqStack &S);//初始化空栈
bool StackEmpty(SqStack S);//判空
void GetTop(SqStack S, SElemType &e);//获得栈顶元素
void Push(SqStack &S, SElemType e);//进栈
void Pop(SqStack &S, SElemType &e);//出栈
void convert(SqStack &S, int N, int n);//十进制转N进制
/*构造一个空栈*/
void InitStack(SqStack &S)
{
S.base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if (!S.base) exit(OVERFLOW); //存储分配失败
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
}
/*栈的判空函数*/
bool StackEmpty(SqStack S)
{
if (S.base == S.top)
return true;
else
return false;
}
/*获得栈顶元素*/
void GetTop(SqStack S, SElemType &e)
{
if (S.top == S.base) return;
else
e = *(S.top - 1);
}
/*进栈*/
void Push(SqStack &S, SElemType e)
{
if (S.top - S.base >= S.stacksize)
{
S.base = (SElemType*)realloc(S.base,(S.stacksize+STACKINCREAMENT)*sizeof(SElemType));
if (!S.base) exit(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREAMENT;
}
*S.top++ = e; //注意:相当于*S.top =e;S.top++;
}
/*出栈*/
void Pop(SqStack &S, SElemType &e)
{
if (S.top == S.base) return;
e = *--S.top; //注意:相当于--S.top;S.top =e;
}
/*数制的转换函数*/
void convert(SqStack &S, int N, int n)
{
InitStack(S);
while (N)
{
Push(S, N % n);
N = N / n;
}
cout << "转换为" << n << "进制之后的数为:";
while (!StackEmpty(S))
{
SElemType e;
Pop(S, e);
cout << e;
}
cout << endl;
}
int main()
{
/*数制的转换过程*/
int n, N;//要转换成的进制数和要转换的数
SqStack s;
InitStack(s);//初始化空栈
cout << "请输入需要十进制数:";
cin >> N;
cout << endl;
cout << "请输入需要转换的进制数:";
cin >> n;
cout << endl;
convert(s, N, n);
}
测试结果如下图。
/*******************************************************************************
数据结构练习
--------------------------------------------------------------------------------
实 验 名: 栈的应用举例
实验说明: 括号检验
时 间: 2017-7-2
作 者: Elvan
*******************************************************************************/
#include
#include //malloc,realloc
#include //含有overflow
#include
using namespace std;
#define STACK_INIT_SIZE 100 //栈的初始空间大小
#define STACKINCREAMENT 10 //增加空间
/*数据类型定义*/
typedef char SElemType;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//----------------函数声明--------------
void InitStack(SqStack &S);//初始化空栈
bool StackEmpty(SqStack S);//判空
void GetTop(SqStack S, SElemType &e);//获得栈顶元素
void Push(SqStack &S, SElemType e);//进栈
void Pop(SqStack &S, SElemType &e);//出栈
bool MatchBracket(SqStack S, char a[]); //括号检测函数
/*构造一个空栈*/
void InitStack(SqStack &S)
{
S.base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if (!S.base) exit(OVERFLOW); //存储分配失败
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
}
/*栈的判空函数*/
bool StackEmpty(SqStack S)
{
if (S.base == S.top)
return true;
else
return false;
}
/*获得栈顶元素*/
void GetTop(SqStack S, SElemType &e)
{
if (S.top == S.base) return;
else
e = *(S.top - 1);
}
/*进栈*/
void Push(SqStack &S, SElemType e)
{
if (S.top - S.base >= S.stacksize)
{
S.base = (SElemType*)realloc(S.base,(S.stacksize+STACKINCREAMENT)*sizeof(SElemType));
if (!S.base) exit(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREAMENT;
}
*S.top++ = e; //注意:相当于*S.top =e;S.top++;
}
/*出栈*/
void Pop(SqStack &S, SElemType &e)
{
if (S.top == S.base) return;
e = *--S.top; //注意:相当于--S.top;S.top =e;
}
/*括号匹配的转换函数*/
bool MatchBracket(SqStack S, char *a)
{
int length = strlen(a);
int i;
SElemType e,x;
for (i = 0; i < length; i++)
{
switch (a[i])
{
case '(':
case '[':
case '{':
case '<': Push(S, a[i]); break;
case ')':{GetTop(S, e);
if (e == '(')
Pop(S, x);
else return false;
}break;
case ']':{GetTop(S, e);
if (e == '[')
Pop(S, x);
else return false; }break;
case '}':{GetTop(S, e);
if (e == '{')
Pop(S, x);
else return false; }break;
case '>':{GetTop(S, e);
if (e == '<')
Pop(S, x);
else return false; }break;
default: break;
}
}
if (StackEmpty(S))
return true;
else return false;
}
int main()
{
cout << "请输入一组括号:";
char a[50];
cin >> a;
SqStack s;
InitStack(s);
if (MatchBracket(s, a))
cout << "括号匹配!" << endl;
else
cout << "括号不匹配!" << endl;
return 0;
}
测试结果如下图。
/*******************************************************************************
数据结构练习
--------------------------------------------------------------------------------
实 验 名: 栈的应用举例
实验说明: 行编辑程序
时 间: 2017-7-2
作 者: Elvan
*******************************************************************************/
#include
#include //malloc,realloc
#include //含有overflow
#include
using namespace std;
#define STACK_INIT_SIZE 100 //栈的初始空间大小
#define STACKINCREAMENT 10 //增加空间
/*数据类型定义*/
typedef char SElemType;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//----------------函数声明--------------
void InitStack(SqStack &S);//初始化空栈
bool StackEmpty(SqStack S);//判空
void GetTop(SqStack S, SElemType &e);//获得栈顶元素
void Push(SqStack &S, SElemType e);//进栈
void Pop(SqStack &S, SElemType &e);//出栈
void ClearStack(SqStack &S); //清空栈
void DestroyStack(SqStack &S); //销毁栈
void LineEdit(); //行编辑程序
/*构造一个空栈*/
void InitStack(SqStack &S)
{
S.base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if (!S.base) exit(OVERFLOW); //存储分配失败
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
}
/*栈的判空函数*/
bool StackEmpty(SqStack S)
{
if (S.base == S.top)
return true;
else
return false;
}
/*获得栈顶元素*/
void GetTop(SqStack S, SElemType &e)
{
if (S.top == S.base) return;
else
e = *(S.top - 1);
}
/*进栈*/
void Push(SqStack &S, SElemType e)
{
if (S.top - S.base >= S.stacksize)
{
S.base = (SElemType*)realloc(S.base,(S.stacksize+STACKINCREAMENT)*sizeof(SElemType));
if (!S.base) exit(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREAMENT;
}
*S.top++ = e; //注意:相当于*S.top =e;S.top++;
}
/*出栈*/
void Pop(SqStack &S, SElemType &e)
{
if (S.top == S.base) return;
e = *--S.top; //注意:相当于--S.top;S.top =e;
}
/*清空栈*/
void ClearStack(SqStack &S)
{
S.top = S.base;
}
/*销毁栈 */
void DestroyStack(SqStack &S)
{
free(S.base);
S.base = S.top = NULL;
S.stacksize = 0;
}
/*利用字符栈S,从终端接收一行并传送至调用过程的数据区*/
void LineEdit()
{
SqStack s;
InitStack(s);
SElemType ch = getchar();
SElemType c;
while (ch != ' ') //按空格结束
{
//EOF为全文结束符
if(ch != ' ' &&ch != '\n')
{
switch (ch)
{
case '#':Pop(s, c); break;
case '@':ClearStack(s); break;
default: Push(s, ch); break;
}
}
else
{
int num = s.top - s.base;
char *pt = new char[num];//建立一个临时字符数组,用来存放从S中弹出的值
while (s.top != s.base)
{
SElemType e;
Pop(s, e);
*(pt++) = e;//将弹出的数据存放到临时字符数组中
}
for (int i = 1; i <= num; i++)
cout << *(--pt);//pt先减1的原因是在(*pt++)操作中当数据输入完成后,pt仍加1,此时因此要先减1
delete[]pt;//销毁临时数组
}
ch = getchar(); //从终端接收下一个字符
}
ClearStack(s);
}
int main()
{
LineEdit();
}
测试结果如下图。
/*******************************************************************************
数据结构练习
--------------------------------------------------------------------------------
实 验 名: 栈的应用举例
实验说明: 迷宫行走
时 间: 2017-7-3
作 者: Elvan
*******************************************************************************/
#include
#include //malloc,realloc
#include //含有overflow
#include
#include
using namespace std;
#define STACK_INIT_SIZE 100 //栈的初始空间大小
#define STACKINCREAMENT 10 //增加空间
#define MAXLEN 10
/*数据类型定义*/
typedef struct
{
int r; //位置的横坐标
int c; //位置的纵坐标
}PosType;
typedef struct
{
int ord;//路径中的“序号”
PosType seat; //“行走位置”
int di; //行走的"方向"
}SElemType;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
typedef struct
{
int r; //迷宫的行数,除去外墙
int c; //迷宫的列数,除去外墙
char adr[MAXLEN][MAXLEN];
}MazeType; //迷宫类型
//----------------函数声明--------------
void InitStack(SqStack &S);//初始化空栈
bool StackEmpty(SqStack S);//判空
void GetTop(SqStack S, SElemType &e);//获得栈顶元素
void Push(SqStack &S, SElemType e);//进栈
void Pop(SqStack &S, SElemType &e);//出栈
void ClearStack(SqStack &S); //清空栈
void DestroyStack(SqStack &S); //销毁栈
void InitMaze(MazeType &maze); //初始化一个迷宫
bool Pass(const MazeType &M, PosType curpos);// 判断当前位置是否可以通过
bool Pass(const MazeType &M, PosType curpos);
PosType NextPos(PosType curpos, int i);
//----------------函数定义--------------
/*构造一个空栈*/
void InitStack(SqStack &S)
{
S.base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if (!S.base) exit(OVERFLOW); //存储分配失败
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
}
/*栈的判空函数*/
bool StackEmpty(SqStack S)
{
if (S.base == S.top)
return true;
else
return false;
}
/*获得栈顶元素*/
void GetTop(SqStack S, SElemType &e)
{
if (S.top == S.base) return;
else
e = *(S.top - 1);
}
/*进栈*/
void Push(SqStack &S, SElemType e)
{
if (S.top - S.base >= S.stacksize)
{
S.base = (SElemType*)realloc(S.base,(S.stacksize+STACKINCREAMENT)*sizeof(SElemType));
if (!S.base) exit(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREAMENT;
}
*S.top++ = e; //注意:相当于*S.top =e;S.top++;
}
/*出栈*/
void Pop(SqStack &S, SElemType &e)
{
if (S.top == S.base) return;
e = *--S.top; //注意:相当于--S.top;S.top =e;
}
/*清空栈*/
void ClearStack(SqStack &S)
{
S.top = S.base;
}
/*销毁栈 */
void DestroyStack(SqStack &S)
{
free(S.base);
S.base = S.top = NULL;
S.stacksize = 0;
}
/*初始化一个迷宫*/
void InitMaze(MazeType &maze)
{
maze.c = 8; //迷宫的行数
maze.r = 8; //迷宫的列数
int i, j;
for (i = 0; i < 10; ++i)
{
//初始化外墙
maze.adr[0][i] = '#';
maze.adr[9][i] = '#';
maze.adr[i][0] = '#';
maze.adr[i][9] = '#';
}
srand(time(NULL));
for (i = 1; i < 9; ++i) //生成迷宫
{
for (j = 1; j < 9; ++j)
{
int i_rand = rand() % 2;
if (i_rand == 1)
maze.adr[i][j] = '1';
else
maze.adr[i][j] = '0';
}
}
}
/*判断当前位置是否可通*/
bool Pass(const MazeType &M, PosType curpos)
{
if (M.adr[curpos.r][curpos.c] == '1')
return true;
else
return false;
}
/*探索下一位置并返回下一位置的坐标 */
PosType NextPos(PosType curpos, int i)
{
PosType nextPos = curpos;
switch (i)
{
case 1:nextPos.c += 1; break;//向东一步
case 2:nextPos.r += 1; break;//向南一步
case 3:nextPos.c -= 1; break;//向西一步
case 4:nextPos.r -= 1; break;//向北一步
default:
exit(0);
}
return nextPos;
}
/*曾走过但不通留下标记*/
void MarkPrint(MazeType &M, PosType curpos)
{
M.adr[curpos.r][curpos.c] = 'x'; //@表示走过但不通
}
/*走过的地方留下足迹*/
void FootPrint(MazeType &M, PosType curpos)
{
M.adr[curpos.r][curpos.c] = '*';//表示可通,用*表示
}
/*寻找迷宫路径*/
bool MazePath(MazeType &M, PosType start, PosType end)
{
//若迷宫M中存在从入口start到出口end的通道,则求得一条存放在栈中,
//并返回TRUE,否则返回FALSE;
SqStack S;
InitStack(S);
SElemType e;
PosType curpos = start; //设定当前位置为入口位置
int curstep = 1; //探索第一步
do
{
if (Pass(M, curpos))
{
//当前位置可以通过,是未曾走过的通道块
FootPrint(M, curpos); //留下足迹
e.ord = curstep;
e.seat = curpos;
e.di = 1;
Push(S, e);//加入路径
if (curpos.r == end.r && curpos.c == end.c) return true;//到达出口
curpos = NextPos(curpos, 1); //下一位置是当前位置的东邻
curstep++; //探索下一步
}
else
{
//当前位置不能通过
if (!StackEmpty(S))
{
Pop(S, e);
while (e.di == 4 && !StackEmpty(S))//栈不空,四周均不通
{
//留下不能通过的标记,并退回一步
MarkPrint(M, e.seat);
Pop(S, e);
}
if (e.di < 4)
{
++e.di;//换下一个方向探索
Push(S, e);
curpos = NextPos(e.seat, e.di);//设定当前位置是该新方向上的相邻块
}
}
}
} while (!StackEmpty(S));
return false;
}
void PrintMaze(const MazeType &M)
{
//输出迷宫
int i, j;
for (i = 0; i < 11; ++i)
{
if (0 == i)
printf(" ");
else
printf("%2d", i - 1);//打印列名
}
printf("\n");
for (i = 0; i < 10; ++i)
{
printf("%2d", i);
for (j = 0; j < 10; ++j)
{
printf("%2c", M.adr[i][j]);
}
printf("\n");
}
}
/*主函数*/
int main()
{
MazeType M;
while (1)
{
InitMaze(M);
cout << "迷宫为:" << endl;
cout << "其中'#'代表外墙,'1'表示通道,'0'表示不可走" << endl;
PrintMaze(M);
PosType In, Out;
cout << "请输入入口坐标:";
cin >> In.r >> In.c;
cout << "请输入出口坐标:";
cin >> Out.r >> Out.c;
if (MazePath(M, In, Out))
{
cout << "其中*表示路径,x表示此路不通:" << endl;
PrintMaze(M);
}
else
cout << "没有通道" << endl;
system("pause");
}
return 0;
}
测试结果如下。