链栈

hello,大家好,又见面了,我是你们的老朋友随 . . .风,今天我们来讲讲链栈的定义,压栈和弹栈

首先,我们需要定义一下头文件,因为用到了malloc函数,所以除了常用的<stdio.h>之外,我们还需要一个<stdlib.h>。

之后,因为我们在之后会用到返回值OK和ERROR,所以可以先预定义一下

    #define OK 1
    #define ERROR 0

然后还需要转换一下类型

    typedef int elemtype;
    typedef int status;

其实用int也行,但是这个格式更符合数据结构的样子

1.定义链栈

一个链栈需要定义些什么呢。我们来想一想,栈,先进后出的一种结构,那肯定就会有一个数据,然后怎么确定前后关系呢,

就要用到指针了,也就是我们说的结点。

typedef struct node{
elemtype data;                    //这个是数据元素
struct node*next;                 //这个就是我们的结点了
}Snode,*linkstack;               //为什么这里会用到两个呢,第一个是真正的链栈称呼,但是我们用第二个就可以使用它的地址了(但愿是这样理解的)

然后我在这里提一下主函数的事情,大家可能看到书上的在定义结点后会出现定义子函数的情况,这肯定是OK的,为什么会直接在这里定义子函数呢,因为你直接写main函数的话,前面不定义,函数运行到main了,它不知道你写的这个函数是什么,它就报错了,所以要么在主函数前面写子函数,要么就先定义。

2.压栈

什么叫压栈,其实就是我们常常说的插入,不过是插入在最前面,也就是我们的 top ,大家想一下,怎么插入,首先,是不是要分配一个地址给我们新定义的 top ,然后就把我们要插进去的值传给 top ,再把 top 和原来的链栈钩起来就好了,然后把地址传给我们最初的栈就好啦 

status push(linkstack *S,elemtype e)
{

  linkstack top;
  top=(linkstack)malloc(sizeof(Snode));         //这个就是内存分配函数 
  if(!top)return ERROR;                                  //如果电脑没得内存分配给我们,我们就只能默默的退出去了  
  top->data=e;
  top->next=*S;
  *S=top;                                                         //为什么这里是*S呢,地址传输不是直接等于就好了吗?大家看看我们的函数定义,是不是有一个*S,前面我们说过了linkstack是一个地址,那我们再*S,是不是就变成了二级指针了呢,二级指针的地址转换,就不是一级指针直接等于就好了
  return OK;

}

3.弹栈

什么叫弹栈,顾名思义,就是把一个元素弹出来,那是哪个元素呢,大家想一下,我们的栈是先进后出的结构,就像一幅牌,你一张一张的把它放在桌子上,然后只能一张一张的拿,你是不是只能从最后放的那张开始,这就是栈。那我们也就知道我们弹的是哪一个元素了,没错,就是最后放进来的那个。怎么删除一个在最后面的元素呢,可以用p->next一直指下去,直到出现NULL为止,就找到了我们的最后一个元素,也可以一开始就设置一个尾结点,但是,但是,大家看看我们的压栈函数,我们是逆序输入的哦,也就是说我们的头指针一直指向我们最后输入的一个元素,所以就很简单了(函数名我就不写了)

  linkstack top;
  top=*S;
  *e=top->data;
  *S=top->next;                            //让S指向下一个元素,就达到了删除的目的
  free(top);                                    //记住要free,不然那个空间就浪费了
  return OK;

好了,就到这里结束啦,呸呸呸,再帮你们写一个printf函数,不然一直在主函数里输出,会显得主函数很乱,主函数越简洁越好

4.输出函数

再谈一下我们的压栈,我们是逆序输入的对吧,那怎么做到顺序输出呢,第一可以设置一个尾结点,然后从后面往前找,第二,我们可以利用一个数组,进行他的赋值,然后逆序输出数组,两者复杂度差不多,看自己喜欢哪个吧,下面给大家讲一下数组的(是我太喜欢数组了,哎)

  linkstack p;
  int i=0,a[10];                                         //定义一个整型的数组,10也行,100也行,也可以在压栈那里设置一个总元素变量,然后然后把那个值返回出来
  p=S;                                                     
  while(p->next!=NULL)                         //这里就是给数组赋值了
  {
  a[i]=p->data;
  p=p->next;
  ++i;
  }
  i=i-1;                                                     //关于这里为什么要i-1,老师说是一开始定义的a[10],那么它就自带了一个地址,逆序的话就会先把地址输出来,我这里取巧的直接给它-1了,哈哈,懂的同学欢迎留言,谢谢
  for(;i>=0;--i)   
  {
  printf("%d ",a[i]);
  }
  printf(" ");

好了,链栈的压栈和弹栈就到这里结束了,大家下期再见!!!

原文地址:https://www.cnblogs.com/tqdlb/p/11715834.html