栈是一种线性的数据结构,它的操作限定在了栈顶,即只能够在栈顶进行数据的插入,删除以及其它各种操作;栈的操作特性为先进后出,下面给出

一张图来说明一下栈的入栈操作。

java入栈顺序 入栈过程_出栈

    通过这个图,发现入栈都是在栈顶进行的,top等于base表示此栈为空栈。上面的入栈顺序为A、B、C、D,在出栈的时候由于只能在栈顶操作,因此

在出栈的时候,顺序就反过来了;所以栈的操作特性就是先进后出。

     另外,栈分为顺序栈和链栈,在这里呢,我是用顺序栈来实现的,个人认为顺栈的实现更简洁方便。另外虽然c++STL标准库里封装了栈结构,并且使用起来

也很方便,但是还是很有必要了解一下它的实现原理的。下面代码详细的写了栈的常见操作,并且测试过了。

1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<malloc.h>
  4 #define MAXSIZE 100
  5 typedef struct
  6 {
  7     int  *top;    //始终指向栈顶的空位置        
  8     int  *base;   //栈底
  9     int  stacksize;  //当前栈的大小
 10 }sqstack;
 11 
 12 int Initstack(sqstack *s)
 13 {
 14     s->base=(int *)malloc(sizeof(int)*MAXSIZE); //为堆栈开辟空间
 15     if(!s->base)    
 16     {
 17        printf("存储分配失败");
 18        exit(-1);
 19     }
 20    s->top=s->base; //空栈的话top和base指向同一位置
 21    s->stacksize= MAXSIZE;
 22    return  1;
 23 }
 24 int push(sqstack *s,int e)   //入栈
 25 {  
 26       if(s->top-s->base==MAXSIZE)
 27       {
 28              printf("堆栈已满,无法入栈\n");
 29              exit(-1);
 30       }
 31       *s->top=e;
 32       s->top++;   //入栈后栈顶指针top指向下一个空位置
 33       //*(s->top)++=e;
 34       return  1;
 35 }
 36 int pop(sqstack *s,int *e)  //出栈
 37 {  
 38       if(s->top==s->base)
 39       {
 40           printf("栈是空的,无法出栈");
 41           return 0;
 42       }
 43       s->top--;  //因为top指向栈顶的下一个位置,是空的,所以要通过自减来指向栈顶元素
 44       *e=*s->top;
 45       return 1;
 46 }
 47 void printstack(sqstack s)  //由于是打印堆栈,不需要修改原来堆栈的值,所以形参设为普通变量就行,不需要设成指针
 48 {         
 49         int *p=s.top;
 50         while(p>s.base)
 51         {
 52          p--;
 53          printf("%d ",*p);  
 54         }   
 55         printf("\n");
 56 }
 57 int Gettop(sqstack s,int *e)  //获取栈顶元素,不需要修改原来堆栈的值,所以形参设为普通变量就行,不需要设成指针
 58 {
 59          if(s.top==s.base)    
 60              return  0;
 61          s.top--;
 62          *e=*s.top;
 63          return   1;
 64 }
 65 int stacklength(sqstack s) //获取栈的长度
 66 {
 67     if(s.top==s.base)
 68         return 0;
 69     else
 70         return(s.top-s.base);
 71 } 
 72 int isempty(sqstack s)  //判断堆栈是否为空
 73 {
 74     if(s.top==s.base)  //空栈返回1,非空返回0
 75         return 1;
 76     else
 77         return 0;
 78 }
 79 void clear(sqstack *s)  //清空堆栈
 80 {
 81     s->top=s->base;
 82 }
 83 int main()
 84 {
 85       int e;
 86       char ch;
 87       sqstack  s;
 88       Initstack(&s);  ///初始化堆栈
 89       printf("输入栈中的元素:\n");
 90       do{
 91            scanf("%d",&e);
 92            push(&s,e);
 93       }while((ch=getchar())!='\n');
 94 
 95       printf("栈中元素为:\n");
 96       printstack(s);
 97       printf("栈的长度为:%d\n", stacklength(s));
 98       Gettop(s,&e);
 99       printf("栈顶元素为:%d\n",e);
100       for(int i=1;i<=5;i++)
101       {
102           pop(&s,&e);
103           printf("第%d次出栈的元素为:%d\n",i,e);     
104       }
105       printf("弹栈后栈中剩余元素为:");
106       printstack(s);
107       printf("弹栈后栈的长度为:%d\n", stacklength(s));
108       Gettop(s,&e);
109       printf("弹栈后栈顶元素为:%d\n",e);
110       printf("结果为1表示空栈,结果为0表示非空栈:%d\n",isempty(s));
111       clear(&s);
112       printf("清空后栈的长度为:%d\n", stacklength(s));
113       printf("结果为1表示空栈,结果为0表示非空栈:%d\n",isempty(s));
114       return 0;
115 }

结果如下:

java入栈顺序 入栈过程_堆栈_02

注意,由于栈是先进后出的,所以栈中数据的顺序和输入的数据顺序是相反的。

2020-04-29   17:10:06