简单介绍堆栈(特点:先进后出)的基本运算
#include <stdio.h>
#include <stdlib.h>
#define maxsize 1000
typedef struct //顺序栈结构
{
int data[maxsize];
int top;
}SeqStack;
SeqStack *Init_SeqStack()//置空顺序栈
{
SeqStack *s;
s=(SeqStack*)malloc(sizeof(SeqStack));
s->top=-1;
return s;
}
int Empty_SeqStack(SeqStack *s)//判断栈是否空
{
if(s->top==-1)return 1;
else return 0;
}
int Push_SeqStack (SeqStack *s,int x)//入栈
{
if(s->top==maxsize-1)return 0;//判断栈满,若栈满,不可入栈,否则会空间溢出
else
{
s->top++;
s->data[s->top]=x;
return 1;
}
}
int Pop_SeqStack(SeqStack *s,int *x)//出栈,地址传递,防数据丢失
{
if(s->top==-1)return 0;//判断栈空,可出栈
else
{
*x=s->data[s->top];//保存下移前栈顶数据,用指针地址传递
s->top--;//栈顶位置下移
reutrn 1;
}
}
int Top_SeqStack(SeqStack *s,int *x)//取栈顶元素
{
if(s->top==-1)return 0;
else
{
*x=*x=s->data[s->top];
return 1;
}
}
链栈的基本操作有判栈空和入栈,相对顺序栈用的较少
typedef struct snode//链栈结构
{
int data;
struct snode *next;
}StackNode,*LinkStack;
LinkStack *top;//定义栈顶指针变量
int Empty_LinkStack(LinkStack top)
{
if(top==NULL)return 1;
else return 0;
}
LinkStack Push_LinkStack(LinkStack top,int x)//入栈
{
StackNode *p;
p=(SeqStack*)malloc(sizeof(SeqStack));
p->data=x;
p->next=top;
top=top->next;
top=p;
}
堆栈的应用实例(运用堆栈“先进后出”的特点)
数制转换问题
将十进制数N转换为r进制数,其转换方法利用辗转相除法
void conversionn(int N,int r)//调用栈的基本操作实现数制转换
{
SeqStack *s;
int x;
s=Init_SeqStack();
while(N!=0)
{
Push_SeqStack(SeqStack *s,N%r);
N=N/r;
}
if(!Empty_SeqStack(s))
{
Pop_SeqStack(SeqStack *s,&x);
printf("%d",x);
}
}
void conversionn(int N,int r)//自定义顺序栈实现数制转换
{
int S[maxsize],top=-1;//定义一个顺序栈并初始化
int x;
while(N!=0)
{
S[++top]=N%r;//余数入栈
N=N/r;//商作为被除数继续
}
while(top!=-1)
{
x=S[top--];
printf("%d",x);
}
}
利用栈实现迷宫问题
这是实验心理学的一个有名实验,我们采取回溯法解决该问题。
(1)设迷宫为m行,n列,将迷宫看成一个maze[m][n]的数组,maze[i][j]=0表示可走,maze[i][j]=1表示不可走,中间的点有八个方向可走,四角则一个方向,四边有五个方向,为使问题简化,我们可把迷宫看成m+2行,n+2列,则所有点都有八个方向可选择,新增四周均设1不可走,与迷宫四周都是墙相一致。
(2)八个方向我们用含数据x,y的结构move表示,由x轴正方向为开始,顺时针进行这八个方向的试探
(3)到达新点我们还需要一个方向序号d表示,若无路可走我们需返回到前一点
(4)为避免到达重复点而进入死循环,我们将到达的点进行标记,置maze[i][j]=-1
下面为核心部分算法
#define m 6
#define n 8
typedef struct //移动结构
{
int x;
int y;
}item;
typedef struct //移动结构
{
int x;
int y;
int d;
}data;
item move[8]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
int path(int maze[m+2][n+2],item move[8])
{
SeqStack *s;
data temp;
int x,y,d,i,j;int tempx,tempy,tempd;
temp.x=1;temp.y=1;temp.d=-1;
Push_SeqStack(s,temp);//入口进栈
while(!Empty_SeqStack(s))
{
Pop_SeqStack(s,&temp);
x=temp.x;y=temp.y;d=temp.d+1;//回到上一坐标位置进行下一坐标试探
while(d<8)//当还有方向可试
{
i=x+move[d].x;j=y+move[d].y;//新点坐标
if(maze[i][j]==0)
{
tempx=x;tempy=y;tempd=d;//记录当前坐标及位置
Push_SeqStack(s,temp);
x=i;y=j;maze[x][y]=-1;//到达新点
if(x==m&&y==n)return 1;//是出口则迷宫有路
else d=0;//不是出口继续试探
}
else d++;
}
}
return 0;
}