2017年第五次课程作业

2017年第五次课程作业链接

作业要求

1.本次作业要求将程序写成.cpp和.h分离的形式
2.根据设计的类图进行编码,搭建主体框架
3.本次作业不要求实现核心的算法功能
4.发表一篇博客,博客内容为:提供本次作业的github链接,对栈的知识学习探索

这学期在上C语言的时候,老师在最后一两次课,有向我们讲了一下关于堆栈的概念,还很贴心的举了一些例子,希望给下个学期的数据结构过渡。并没有教我们如何编码,那个时候的堆栈题目可惜的是没有去做,所以这次是一个机会,一个学习堆栈的机会。刚开始的时候是在网上检索,结果并没有发现特别好的相关知识,最终去了图书馆。在图书馆里没有专门介绍堆栈的书籍,可能是因为堆栈的知识太少不足以出书,在在数据结构的第三、四章有介绍堆栈。

堆栈的学习

堆栈的概念

在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构。堆栈都是一种按序列排序的数据结构,只能在一端(称为栈顶(top)对数据进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。要点:队列,先进先出;栈,先进后出

1.栈的概念
栈是一种特殊的线性表,其特殊性体现在元素插入和删除运算上,它的插入和运算仅限定在表的某一端进行,不能在表中间和另一端进行。允许进行插入和删除的一端称为栈顶,另一端称为栈底。处于栈顶位置的数据元素称为栈顶元素。不含任何数据元素的栈称为空栈。举一个例子说明,假设有一个很窄的死胡同,胡同里能容纳若干个人,但是每次只允许一个人进出。这里人进出死胡同的原则是先进去的后出来。
2.栈的基本运算

  • 初始化栈:InitStack(st),建立一个空栈st.
  • 销毁栈:destroyStack(st),释放栈st占用的内存空间。
  • 进栈:Push(st,x),将元素x插入栈st中,使x成为栈st的栈顶元素。
  • 出栈:Pop(st,x),当栈st不空时,将栈顶元素赋给x,并从栈中删除当前栈顶。
  • 取栈顶元素:GetTop(st),若栈不空时,返回栈顶元素;当栈st为空时,结果为一特殊标识(ERROR)。
  • 判断栈空:StackEmpty(st),判断栈st是否为空栈。

3.栈的顺序存储结构
栈的顺序存储结构称为顺序表。顺序栈通常由一个一维数组data和一个记录顶元素位置的top组成。习惯上将栈低放在数组下标小的那端,栈顶元素由栈顶指针top所指向。

  • 3.1顺序栈的定义如下:
#define MaxSize 100  //顺序栈的初始分配空间大小
typedef struct    
{
    ElemType data[MaxSize]; //保存栈中的元素,这里假设ElemType为char 类型
    int top;  //栈顶指针
}Sqstack;

在上述顺序栈定义中,ElemType为栈元素的数据类型,那么在这里表示的是一个字符型的栈;MaxSize为一个常量,表示data数组中最多可放的元素个数,因为数组的下标是从0开始的,所以data元素的下标范围为0~MaxSize-1;当top=-1时表示栈空,当top=MaxSize-1时表示栈满。
归纳起来,对于顺序栈st,其初始位置st.top=-1,它的四个要素:(1)栈空条件:st.top==-1;(2)栈满条件:st.top==MaxSize-1;(3)元素进栈操作:st.top++;将元素x放在st.data[st.top]中;(4)出栈元素x的操作:取出栈元素x=st.data[st.top];top--。

  • 3.2初始化栈运算算法:其主要操作是设定栈顶指针top为-1。算法如下:
void InitStack(SqStack &st) //st为引用型参数
{
    st.top=-1;
}
  • 3.3销毁栈运算算法:这里顺序栈的内存空间是系统自动分配的,在不再需要时系统自动释放其空间。算法如下:
void DestroyStack(SqStack st)
{    }
  • 3.4进栈运算算法:其主要操作是:进栈指针加一,将进栈元素放在栈顶处。算法如下:
int Push(SqStack &st,ElemType x)
{
    if(st.top==MaxSize-1)return 0;   //栈满上溢返回0
    else 
    {
      st.top++;
      st.data[st.top]=x;
      return 1;         //成功进栈返回1
    }
}
  • 3.5出栈运算算法:其主要操作是:先将栈顶元素取出,然后将栈顶指针减一。算法如下:
int Pop(SqStack &st,ElemType &x)  //x为引用型参数
{
    if(st.top==-1)return 0;    //栈空返回0
    else 
    {
        x=st.data[st.top];
        st,top--;
        return 1;     //成功出栈返回1
    }
}
  • 3.6取栈顶元素运算算法:其主要操作是:将栈指针top处的元素取出赋给变量x。算法如下:
int GetTop(SqStack &st,ElemType &x)  //x为引用型参数
{
    if(st.top==-1)return 0;    //栈空返回0
    else 
    {
        x=st.data[st.top];
        return 1;     //成功取栈顶元素返回1
    }
}
  • 3.7判断栈空运算算法:其主要操作是:若栈为空(top==-1)则返回值0,,否则返回值1。算法如下:
int StackEmpty(SqStack st)
{
    if(st.top==-1)return 0;
    else return -1;
}
  • 3.8举例:回文指的是一个字符串从前面和从后面读都一样,如“123454321"、"abcba"都是回文。设计一个算法利用顺序栈的运算判断一个字符串是否为回文。
    思路:因为回文是从前到后以及从后到前都是一样的,所以只要将待判断的字符串颠倒,然后与原字符串相比较,就可以决定是否为回文了。算法如下:
intishw(char str[])  //判断给定字符串str是否回文,是返回1,否则返回0
{
    SqStack st;    //定义一个顺序栈st
    InitStack(st);   //栈初始化
    int i=0;char ch;
    while((ch=str[i++])!='\0')Push(st,ch);   //所有字符依次进栈
    i=0;           //从头开始遍历str
    while(!StackEmpty(st))  //栈不空循环
    {
        Pop(st,ch);
        if(ch!=str[i++])    //两字符不相同时返回0
        {
            DestroyStack(st);
            return 0;
        }
    }
    DestoryStack(st);
    return 1;      //所有相应字符都相同的时候返回1
}

4.栈的链式存储结构
栈的链式存储结构是采用某种链表结构,栈的链表存储结构简称为链栈。和链表的知识有一定的相关联,这里采用单链表作为链栈。

  • 4.1链栈的定义如下:
typedef struct node
{
    ElemType data; //存储结点数据,这里假设ElemType为char类型
    struct node *next; //指针域
}LinkStack;

单链表的第一个结点就是链栈的栈顶结点,通常有一个指向栈顶的指针head,这里采取栈顶指针为ls.类似地,栈由栈顶指针ls唯一确定,栈中的其他结点通过它们的next域链接起来,栈底结点的next域为NULL。因为链栈本身没有容量限制,所以不考虑栈满的情况。
归纳起来,链栈ls初始时ls=NULL,其4个要素如下:(1)栈空条件:ls==NULL;(2)栈满条件:不考虑;(3)元素x进栈操作:创建存放元素x的结点*p,将其插入到栈顶位置上;(4)出栈元素x操作:置x为栈顶结点的data域,并删除该节点。

  • 4.2初始化栈运算算法:其主要操作是:创建一个栈头结点*ls,用ls=NULL标识栈为空栈。算法如下:
void InitStack(LinkStack *&ls)   //ls为引用型参数
{
    ls=NULL;
}
  • 4.3销毁栈运算算法:链栈的所有结点空间都是通过malloc函数分配的,在不需要时需通过free函数释放所有结点的空间。算法如下:
void DestroyStack(LinkStack *&ls)
{
    LinkStack *pre=ls,*p;
    if(pre==NULL)return ; //考虑空栈的情况
    p=pre->next;
    while(p!=NULL)
    {
        free(pre);     //释放*pre结点
        pre=p;      //pre、p同步后移
        p=p->next;
    }
    free(pre);      //释放尾结点
}
  • 4.4进栈运算算法:其主要操作是:先创建一个新的结点,其data域值为x;然后将该结点插入到*ls结点之后作为栈顶结点。算法如下:
void Push(LinkStack *&ls,ElemType x)   //ls为引用型参数
{
    LinkStack *p;
    p=(LinkStack *)malloc(sizeof(LinkStack));
    p->data=x;   //创建结点*p用于存放x
    p->next=ls;   //插入*p结点作为栈顶结点
    ls=p;
}
  • 4.5出栈运算算法:其主要操作是:将栈顶结点(即ls所指结点)的data域值赋给x;然后删除该栈顶结点。算法如下:
int Pop(linkStack *&ls,Elemtype &x)  //ls为引用型参数
{
    Linkstack *p; 
    if(ls==NULL)return 0;   //栈空,下溢出返回0
    else
    {                   //栈不空时出栈元素x并返回1
        p=ls;     //p指向栈顶结点
        x=p->data;    //取栈顶元素x
        ls=p->next;   //删除结点*p
        free(p);    //释放*p结点
        return 1;
    }
}
  • 4.6取栈顶元素运算算法:其主要操作是:将栈顶结点(即ls所指结点)的data域值赋给x。算法如下:
int GetTop(LinkStack *ls,ElemType &x)
{
    if(ls==NULL)return 0;  //栈空,下溢出时返回0
    else 
    {
        x=ls->data;  //栈不空,取栈顶元素x并返回1
        return 1;
    }
}
  • 4.7判断栈空运算算法:1其主要操作是:若栈为空(即ls==NULL)则返回值1,否则返回值0。算法如下:
int LinkStack(LinkStack  *ls)
{
    if(ls==NULL)return 1;
    else return 0;
}
  • 4.8举例设计一个算法,判断一个可能含有小括号(“(”和“)”)、中括号("["和"]")和大括号("{"和"}")的表达式中各类括号是否匹配。若匹配,则返回1;否则返回0。例如:[()],匹配;{(}),不匹配。
    思路:设置一个栈st(这里用字符数组存放栈中的元素,另用一个整型变量top作为栈顶指针),用i扫描表达式exps,不考虑非括号字符。算法如下:
int mach(char *exps)   //exps存放表达式
{
    char st[MaxSize];
    int nomatch=1,top=-1,i=0;
    while(exps[i]!='\0'&&nomatch==1)   //遍历表达式exps
    {
        switch(exps[i])
        {
            case'(':case'[':case'{':    //左括号进栈
                top++;st[top]=exps[i];break;
            case'(':                    //遇到“)”
                if(st[top]==')')top--;  //判断栈顶是否为“(”
                else nomatch=0;
                break;
            case'[':                        //遇到“]”
                if(st[top]==']')top--;
                //判断栈顶是否为“[”
                else nomatch=0;
                break;
            case'{':                  //遇到“}” 
                if(st[top]=='}')top--;
                //判断栈顶是否为“{”
                else nomatch=0;
                break;
            default:
            //跳过其他字符
                break;
        }
        i++;
    }
    if(nomatch==1&&top==-1)return 1;
    //栈空且符号匹配则返回1
    else return 0;
    //否则返回0
}

感想

这次自学栈的知识,举的两个例子都是上C语言课程的时候,老师有提到的典例,通过这次学习终于知道怎么回事了。栈的链式结构与链表有一点相似,但是栈只允许在栈顶进行相关操作,相比之下,栈显得更加简单。

代码问题

这次没有编写代码,所以就没有相关链接......

转载于:https://www.cnblogs.com/mysoul-/p/6890956.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值