堆栈的操作
栈是一种线性的数据结构,它的操作限定在了栈顶,即只能够在栈顶进行数据的插入,删除以及其它各种操作;栈的操作特性为先进后出,下面给出
一张图来说明一下栈的入栈操作。
通过这个图,发现入栈都是在栈顶进行的,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 }
结果如下:
注意,由于栈是先进后出的,所以栈中数据的顺序和输入的数据顺序是相反的。
2020-04-29 17:10:06