数据结构之栈

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;  
}  

 

 

转载于:https://my.oschina.net/lin546/blog/1554701

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值