栈的基本操作(小系统)(base,top)

栈的基本操作
包含九个基本操作
如下:

#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/malloc.h>

#define  OK    1
#define  ERROR 0
#define  STACK_INIT_SIZE  100
#define  STACKINCREMENT  10
typedef int ElemType;
typedef int Status;

//栈的顺序结构表示
typedef struct {
    ElemType *base;
    ElemType *top;
    int stacksize;
}SqStack;

//1.构建一个空栈
Status InitStack(SqStack *S){
    S->base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));
    if(!S->base){
        printf("存储分配失败");
        exit(-1);
    }
    S->top=S->base;
    S->stacksize=STACK_INIT_SIZE;
    return OK;
      
}

//2.进栈
Status Push(SqStack *S,ElemType e){
    if(S->top-S->base>=STACK_INIT_SIZE){
        S->base=(ElemType *)realloc(S->base, (S->stacksize+STACKINCREMENT)*sizeof(ElemType));
        if(!S->base)
            return ERROR;
        S->top=S->base+STACK_INIT_SIZE;//栈底地址可能改变,重新定位栈顶元素
        S->stacksize=S->stacksize+STACKINCREMENT;
    }
    *S->top=e;
    S->top++;
    return OK;
}

//3.出栈/获取栈顶元素
Status Pop(SqStack *S,ElemType *e){
    if(S->top==S->base)
        return ERROR;
    else{
        S->top--;
        *e=*S->top;
        return *e;
    }
}

//4判断栈是否为空
Status StackEmpty(SqStack *S){
    if(S->top==S->base)
        return ERROR;
    else
        return OK;
}

//5.求栈的长度
Status StackLength(SqStack *S){
    if(S->top==S->base)
        return ERROR;
    else
        return (Status)(S->top-S->base);
       
}

//6.求栈顶元素
Status GetTop(SqStack *S,ElemType *e){  //SqStack *S 和 SqStack S都可以,传地址更节约时间空间
    if(S->top==S->base)
        return ERROR;
    else
        *e=*(S->top-1);
    return *e;
}


//7.清空栈
Status ClearStack(SqStack *S){
    S->top=S->base;
    return OK;
}

//8.销毁栈
Status DestroyStack(SqStack *S){
    S->top=NULL;
    S->stacksize=0;
    free(S->base);
    return OK;
}

//9.遍历栈/打印栈
Status StackTraverse(SqStack *S){
    if(S->base==NULL)
        return ERROR;
    if(S->top==S->base)
        printf("栈中没有元素。。。\n");
    ElemType *p;
    p=S->top;
    while (p>S->base) {
        p--;
        printf("%d",*p);
    }
    printf("\n");
    return OK;
}
int main(int argc, const char * argv[]) {
    SqStack S;
    int sele,i,n;
    Status a,e;
    do {
        printf("********************\n");
        printf("    1.构造一个空栈     \n");
        printf("    2.入栈            \n");
        printf("    3.出栈            \n");
        printf("    4判断栈是否为空。   \n");
        printf("    5.求栈的长度       \n");
        printf("    6.求栈顶元素       \n");
        printf("    7.清空栈          \n");
        printf("    8.销毁栈          \n");
        printf("    9.打印栈           \n");
        printf("    0.退出             \n");
        printf("********************\n");
        printf("请输入你要进行的操作:\n");
        scanf("%d",&sele);
        switch (sele) {
            case 1:
                InitStack(&S);
                printf("创建成功!\n");
                break;
            case 2:
                printf("请输入栈的长度:\n");
                scanf("%d",&n);
                for (i=1; i<=n; i++) {
                    scanf("%d",&e);
                    Push(&S, e);
                }
                printf("已全部入栈!\n");
                break;
            case 3:
                printf("出栈元素是:\n");
                printf("%d",Pop(&S, &e));
                printf("\n");
                break;
            case 4:
                if(StackEmpty(&S))printf("栈不为空!\n");
                else printf("栈为空!\n");
                break;
            case 5:
                printf("栈的长度是:\n");
                a=StackLength(&S);
                printf("%d",a);
                printf("\n");
                break;
            case 6:
                printf("栈顶元素是:\n");
                e=GetTop(&S, &e);
                printf("%d",e);
                printf("\n");
                break;
            case 7:
                if (ClearStack(&S)) {
                    printf("栈已清空!\n");
                }else
                    printf("清空失败!\n");
                break;
            case 8:
                if(DestroyStack(&S)) printf("销毁栈成功!\n");
                else printf("销毁栈失败!\n");
                break;
            case 9:
                printf("栈内元素是:\n");
                StackTraverse(&S);
                break;
            default:
                sele=0;
                exit(0);
                break;
        }
    } while (sele);

}

感悟:
开始写主函数时一直困惑
int main(){
SqStack *S;
InitStack(S);
}
这样子设置结构体类型指针S传给InitStack(),Push(),Pop()等函数不行,后来我明白:SqStack *S只是定义了一个指针,但是这个指针里面的地址内容是空的,也就是说指针没有指向任何东西。把这个指针传给函数时会出错。

为了便于理解,可以设置一个结构体类型的变量,让指针指向此变量,也就是把此变量的地址给指针,然后再给函数传指针就可以通过了。
int main(){
SqStack *S;
SqStack s1;
S=&s1;
InitStack(S);
}

而函数中 InitStack(SqStack *S),Push(SqStack *S,ElemType e)等SqStack *S也是为了设置形参变量来接收结构体变量的地址。
很明显上面主函数里设置指针变量没必要所以直接设置结构体变量,传其地址即可
int main(){
SqStack S;
InitStack(&S);
}

求栈的长度部分
顺序栈栈顶栈底地址相减可以得到栈的长度
开始疑惑为什么不能是 return ((S->top)-(S->base));
这其实是返回栈顶内容与栈底内容相减的结果。

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值