栈的c语言实现

#include <stdio.h>
#include <stdlib.h>

// 栈 后进先出

typedef int SElemType; // 任意数据类型


typedef int Status;   // 函数返回数据类型

#define TRUE 1
#define OK 1
#define FALSE 0
#define ERROR -1
#define OVERFLOW -2

#define STARKINIT 100
#define INCREMENT 10

typedef struct{
    SElemType *base;  // 在栈构造之前和销毁之后,值为NULL
    SElemType *top;   // 栈顶指针
    int stackSize;    // 当前已分配的存储空间(单位:元素)
}SqStack;

// 构造一个空栈
Status InitStact(SqStack *S){
    // base申请初始长度的存储空间,并指向第一个地址
    S->base = (SElemType *)malloc(STARKINIT * sizeof(SElemType));
    if(!S->base) exit(OVERFLOW);
    S->top = S->base;
    S->stackSize = STARKINIT;
    return OK;
}

// 销毁栈
Status DestroyStack(SqStack *S){
    free(S);
    return OK;
}

// 将S置空
Status ClearStack(SqStack *S){
    S->top = S->base;
    return OK;
}

// 判断S是否为空,是返回TRUE,否返回FALSE
Status StackEmpty(SqStack S){
    if(S.top == S.base) return TRUE;
    return FALSE;
}

// 返回S的元素个数
int StackLength(SqStack S){
    return S.top-S.base;
}

// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
Status GetTop(SqStack S, SElemType *e){
    // 若头指针还是指向第一个,说明根本没有存过数据元素,即为空
    if(S.top == S.base) return ERROR;
    // 不为空e指向栈顶地址(即为top-1的指针指向的地址)
    *e = *(S.top-1);
    return OK;
}

// 插入元素e为新的栈顶元素
Status Push(SqStack *S, SElemType e){
    // 若top指向已经大于当前已申请的存储空间
    if(S->top - S->base >= S->stackSize){
        // 申请新的存储空间
        S->base = (SElemType *)realloc(S->base,(S->stackSize + INCREMENT)* sizeof(SElemType));
        if(!S->base) exit(OVERFLOW);
        // top指向新申请部分的指针的第一位
        S->top = S->base + S->stackSize;
        S->stackSize += INCREMENT;
    }
    // 在当前指针位置存入数据元素e然后top++
    *S->top++ = e;
    return OK;
}

// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status Pop(SqStack *S, SElemType *e){
    if(S->top == S->base) return ERROR;
    // e获得栈顶元素值,然后top--
    *e = * --S->top;
    return OK;
}

// 从栈底到栈顶依次对栈中每个元素调用函数visit()。一旦visit失败,则操作失败
Status StackTraverse(SqStack S, Status (*visit)()){

}

// 将输入的任意非负十进制整数转换成八进制
void conversation(){
    SqStack S;
    InitStact(&S);
    int n;
    printf("请输入一个非负十进制整数:");
    scanf("%d",&n);
    while(n){
        Push(&S,n%8);
        n = n/8;
    }
    printf("对应八进制整数:");
    while(!StackEmpty(S)){
        SElemType e;
        Pop(&S,&e);
        printf("%d",e);
    }
    printf("\n");
}

// 括号匹配的检验
void getBracket(){
    SqStack S;
    InitStact(&S);
    printf("请输入括号总数:");
    int n,f=1;
    scanf("%d",&n);
    if(n%2 != 0){
        printf("括号总数非法!\n");
        exit(0);
    }
    printf("请依次输入括号:");
    char c;
    rewind(stdin);
    while(n){
        SElemType e;
        scanf("%c",&c);
        e = c;
        if(f == 0);
        else if(c == '[' || c == '(') Push(&S,c);
        else{
            GetTop(S,&e);
            if((c==']' && e=='[') || (c==')' && e=='(')) Pop(&S,&e);
            else f=0;
        }
        --n;
    }
    if(f) printf("括号匹配合法!\n");
    else printf("括号匹配非法!\n");
}

// 行编辑程序
void LineEdit(){
    SqStack S;
    InitStact(&S);
    char ch = getchar();
    SElemType c;
    while(ch != EOF){
        while(ch != EOF && ch != '\n'){
            switch(ch){
                case '#':Pop(&S,&c);break;
                case '@':ClearStack(&S);break;
                default:Push(&S,ch);
            }
            ch = getchar();
        }

        // 存进缓冲区,我懒得写了,直接输出
        while(!StackEmpty(S)){
            SElemType e;
            Pop(&S,&e);
            printf("%c",e);
        }
        printf("\n");
        ClearStack(&S);
        if(ch != EOF) ch = getchar();
    }
    DestroyStack(&S);
}



int main()
{
    LineEdit();

    SqStack S;
    InitStact(&S);
    printf("请输入需要插入栈的数据元素的个数:");
    int n;
    scanf("%d",&n);
    printf("请输入数据元素:");
    SElemType e;
    for(int i=0; i<n; i++){
        scanf("%d",&e);
        Push(&S,e);
    }

    printf("共插入了%d个数据元素\n",StackLength(S));

    printf("栈内的元素为:");
    for(int i=0; i<n; i++){
        Pop(&S,&e);
        printf("%d ",e);
    }
    printf("\n");

    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值