1、栈的顺序存储结构
#include<stdio.h>
#include<stdlib.h>
#define MAXNUM 20
#define ElemType int
/*定义顺序栈的存储结构*/
typedef struct
{ ElemType stack[MAXNUM];
int top;
}SqStack;
/*初始化顺序栈*/
void InitStack(SqStack *p)
{ if(!p)
printf("Eorror");
p->top=-1;
}
/*入栈*/
void Push(SqStack *p,ElemType x)
{ if(p->top<MAXNUM)
{ p->top=p->top+1;
p->stack[p->top]=x;
}
else
printf("Overflow!\n");
}
/*出栈*/
ElemType Pop(SqStack *p)
{ ElemType x;
if(p->top!=0)
{ x=p->stack[p->top];
printf("以前的栈顶数据元素%d已经被删除!\n",p->stack[p->top]);
p->top=p->top-1;
return(x);
}
else
{ printf("Underflow!\n");
return(0);
}
}
/*获取栈顶元素*/
ElemType GetTop(SqStack *p)
{ ElemType x;
if(p->top!=0)
{ x=p->stack[p->top];
return(x);
}
else
{ printf("Underflow!\n");
return(0);
}
}
/*遍历顺序栈*/
void OutStack(SqStack *p)
{ int i;
printf("\n");
if(p->top<0)
printf("这是一个空栈!");
printf("\n");
for(i=p->top;i>=0;i--)
printf("第%d个数据元素是:%6d\n",i,p->stack[i]);
}
/*置空顺序栈*/
void setEmpty(SqStack *p)
{
p->top= -1;
}
/*主函数*/
main()
{ SqStack *q;
int y,cord;ElemType a;
do{
printf("\n");
printf("第一次使用必须初始化!\n");
printf("\n");
printf("\n 主菜单 \n");
printf("\n 1 初始化顺序栈 \n");
printf("\n 2 插入一个元素 \n");
printf("\n 3 删除栈顶元素 \n");
printf("\n 4 取栈顶元素 \n");
printf("\n 5 置空顺序栈 \n");
printf("\n 6 结束程序运行 \n");
printf("\n--------------------------------\n");
printf("请输入您的选择( 1, 2, 3, 4, 5,6)");
scanf("%d",&cord);
printf("\n");
switch(cord)
{ case 1:
{ q=(SqStack*)malloc(sizeof(SqStack));
InitStack(q);
OutStack(q);
}break;
case 2:
{ printf("请输入要插入的数据元素:a=");
scanf("%d",&a);
Push(q,a);
OutStack(q);
}break;
case 3:
{ Pop(q);
OutStack(q);
}break;
case 4:
{ y=GetTop(q);
printf("\n栈顶元素为:%d\n",y);
OutStack(q);
}break;
case 5:
{ setEmpty(q);
printf("\n顺序栈被置空!\n");
OutStack(q);
}break;
case 6:
exit(0);
}
}while (cord<=6);
}
//栈顶指针:S.top,初始时设置S.top=-1;栈顶元素:S.data[S.top]。
//进栈操作:栈不满时,栈顶指针先加1,再送值到栈顶元素。
//出栈操作:栈非空时,先取栈顶元素值,再将栈顶指针减1。
//栈空条件:S.top=-1;栈满条件:S.top==MaxSize-1;栈长:S.top+1。
2、栈的链式存储结构
栈顶放在单链表的头部,对于空栈来说,链表原定义是头指针指向空,所以链栈的空其实就是top==NULL的时候。
链栈的结构代码如下:
typedef struct StackNode
{
int data;
struct stackNode *next;
}StackNode,*LinkStackPtr;
typedef struct LinkStack{
LinkStackPtr top;
int count;
} LinkStack;
链栈的操作大部分被和单链表相似,只是在插入和删除上,特殊一点。
进栈操作
对于链栈的进栈push操作,假设元素值e的新节点是s,top为栈顶指针
statue push(LinkStack *S,int e)
{
LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));
s->data=e;
s->next=S->top;//将当前的栈顶元素赋值给新节点的直接后继
S->top=s; //将新节点s赋值给栈顶指针
S->count++;
return OK;
}
出栈操作
假设变量p用来存储要删除的栈顶节点,将栈顶指针下移一位,最后释放p即可。
//若栈不空,则删除栈顶元素,用e返回其值,并返回OK
Statue pop(LinkStack *S,int *e)
{
LinkStackPtr p;
if(StackEmpty(*S))
return error;
*e=S->top->data;
p=S->top;//将栈顶元素赋值给p
S->top=S->top->next;//使得栈顶指针下移一位,指向后一节点。
free(p);
s->count--;
return OK;
}
3、共享栈
即是两个栈使用同一段存储空间。
第一个栈从数组头开始存储,第二个栈从数组尾开始,两个栈向中间拓展。
当top1+1==top2或者top1==top2-1时,即staock overflow!.
与普通栈一样,共享栈出栈入栈的时间复杂度仍为O(1).
数据结构
typedef struct shareStack{ int data[MAXSIZE]; int top1; int top2; }shareStack;
出栈操作
该数据,仅存的是非负数,因此如果想要存储更复杂的操作,可以在判断栈空时,换一种方式,即可。
int Pop(shareStack *ss,int flag){ if(flag == 1){ if(ss->top1 == -1) return -1; return ss->data[ss->top1--]; }else if(flag == 2){ if(ss->top2 == MAXSIZE) return -1; return ss->data[ss->top2++]; } return -1; }
入栈操作
int Push(shareStack *ss,int num,int flag){ if(ss->top1+1 == ss->top2) return 0; if(flag == 1){ ss->data[++ss->top1] = num; return 1; }else if( flag == 2){ ss->data[--ss->top2] = num; return 1; } return 0; }
示例代码
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
typedef struct shareStack{
int data[MAXSIZE];
int top1;
int top2;
}shareStack;
void createStack(shareStack * ss,int n,int m);
void showStack(shareStack *ss);
int Push(shareStack *ss,int num,int flag);
int Pop(shareStack *ss,int flag);
int main()
{
shareStack * ss = (shareStack *)malloc(sizeof(shareStack));
createStack(ss,3,4);
showStack(ss);
if(Push(ss,6,1))
showStack(ss);
if(Push(ss,4,2))
showStack(ss);
int n;
n=Pop(ss,1);
if(n>=0)
printf("the pop num is:%d\n",n);
n=Pop(ss,2);
if(n>=0)
printf("the pop num is:%d\n",n);
n=Pop(ss,1);
if(n>=0)
printf("the pop num is:%d\n",n);
n=Pop(ss,1);
if(n>=0)
printf("the pop num is:%d\n",n);
n=Pop(ss,1);
if(n>=0)
printf("the pop num is:%d\n",n);
n=Pop(ss,1);
if(n>=0)
printf("the pop num is:%d\n",n);
n=Pop(ss,1);
if(n>=0)
printf("the pop num is:%d\n",n);
showStack(ss);
return 0;
}
void createStack(shareStack * ss,int n,int m){
int i;
ss->top1 = -1;
ss->top2 = MAXSIZE;
for(i=0;i<n;i++){
ss->top1++;
ss->data[ss->top1] = 2*i+1;
}
for(i=0;i<m;i++){
ss->top2--;
ss->data[ss->top2] = 2*i+1;
}
}
void showStack(shareStack *ss){
int i;
for(i=0;i<ss->top1+1;i++){
printf("%d->",ss->data[i]);
}
printf("top1-----top2");
for(i=ss->top2;i<MAXSIZE;i++){
printf("<-%d",ss->data[i]);
}
printf("\n");
}
int Push(shareStack *ss,int num,int flag){
if(ss->top1+1 == ss->top2)
return 0;
if(flag == 1){
ss->data[++ss->top1] = num;
return 1;
}else if( flag == 2){
ss->data[--ss->top2] = num;
return 1;
}
return 0;
}
int Pop(shareStack *ss,int flag){
if(flag == 1){
if(ss->top1 == -1)
return -1;
return ss->data[ss->top1--];
}else if(flag == 2){
if(ss->top2 == MAXSIZE)
return -1;
return ss->data[ss->top2++];
}
return -1;
}