《大话数据结构》第四章学习笔记(一)

栈的定义(后进先出)

定义

栈是限定仅在表尾进行插入的删除操作的线性表

 我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何 数据元素的栈称为空栈。栈又称为后进先出的线性表,简称LIFO结构。

注意:

栈是一个线性表,也就是说栈元素具有线性关系,即前驱后继关系。

栈的特殊之处在于限制了这个线性表的插入和删除位置,它始终在栈顶进行。这也就使得:栈底是固定的,最先进栈的只能在栈底。

栈的插入操作,叫作进栈,也称压栈、入栈。

栈的删除操作,叫作出栈,也称弹栈。

栈的引用简化了程序设计的问题,划分了不同关注层次,使得思考范围缩小,更加聚焦于我们要解决问题的核心。

进栈出栈变化形式

牢记一点,栈是后进先出的。

打个比方:1,2,3按顺序进栈,那么合理的出栈顺序有很多种

比如:3,2,1或者1,2,3或者2,1,3或者1,3,2或者2,3,1

但是像3,1,2这种出栈顺序就不可能,因为如果3先出栈,那么意味这1,2已经入栈,那么2就一定要比1先出栈。

这让我想起我之前做了一个判断出栈的合法顺序的题目;

例题:输入n,和一个序列,代表需要判断的出栈顺序,如果合理输出yes,不合理输出no

样例:

输入:3                                                                    输出:yes

           3 2 1                                          

#include
int main()
{
    int n,i,j,a[100],b[100];
    while(~scanf("%d",&n))
    {
        if(n==0)break;
        int top=0,di=0,k=0;
        for(i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
        }
        for(i=1; i<=n; i++)
        {
            for(j=di+1; j<=a[i]; j++)
            {
                di=j;
                b[top++]=j;//入栈
            }
            if(b[--top]!=a[i])//出栈并比较
                k++;
        }
        if(k>0)printf("No\n");
        else printf("Yes\n");
    }
    return 0;
}

栈的顺序存储结构及实现

栈的顺序存储结构

栈的顺序存储结构是线性表顺序存储的简化,简称为顺序栈。用数组来实现。

定义top来表示栈顶元素在数组中的位置,top初始值为-1,当栈中有一个元素时top=0;

《大话数据结构》第四章学习笔记(一)_第1张图片

《大话数据结构》第四章学习笔记(一)_第2张图片

 

 

 

 

 

 

 

 

 进栈与出栈

//入栈
void push(int *s,int a)//a为要入栈的元素
{
   if(s->top==max-1)//栈满时
       return error;
   s->top++;//栈顶指针加一
   s->date[s->top]=a;//入栈
   return OK;
}



//出栈
void pop(int *s,int a)//用a来接收要出栈的元素
{
   if(s->top==-1)//栈空时
      return error;
   a=s->date[s->top];//将要出栈的元素赋给a
   s->top--;//栈顶指针减一
   return OK;
}

两栈共享空间

当两个具有相同数据类型的栈,我们可以考虑让两栈共享一个空间。

只需要让top1指向数组的始端,让top2指向数组的终端,然后向中间靠拢,当top1+1=top2时栈满。

栈的链式存储结构及实现

栈的链式存储结构(简称链栈)

用链表来实现栈,此时栈顶指针其实就是链表的头指针,将栈顶放在链表的头部。

对于链栈来说,基本不存在栈满的情况,除非内存已经没有使用空间。空栈时即为top=NULL时。

链栈的操作与绝大部分的单链表类似,只是在插入和删除上特殊一点。

出栈和入栈

//入栈
void push(Linklist *S,int a)
{
   Linklistptr s=(Linklistptr)malloc(sizeof(node));
   s->date=a;
   s->next=S->top;
   S->top=s;
   S->count++;
   return ok;
}


//出栈
void pop(Linklist *S,int a)
{
  Lintklistptr p;
  if(stsckempty(*S))
     return error;
  a=S->top->date;
  p=S->top;
  S->top=S->top->next;
  free(p);
  S->count--;
  return ok;
}

如果栈的输赢过程中元素变化不可预料,有时很小,有时非常大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈会更好一点。

你可能感兴趣的:(学习总结,数据结构,散列表,栈)