数据结构---堆栈

简单介绍堆栈(特点:先进后出)的基本运算

#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;
}

猜你喜欢

转载自blog.csdn.net/weixin_42107106/article/details/82820852