C语言之链栈的操作

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

typedef char SElemType;

typedef struct StackNode
{
    SElemType data;         //存的数据
    struct StackNode *next; //栈顶
}StackNode, *LinkStack;
LinkStack s;                //指向栈顶(也是链表的头指针)

LinkStack InitStack();              //空栈构造函数
void DestroyStack(LinkStack s);     //销毁栈函数
LinkStack ClearStack(LinkStack s);  //清除栈
int StackEmpty(LinkStack s);        //判断是否为空栈,是返回1,否 返回0
int StackLength(LinkStack s);       //返回栈的长度
void Push(SElemType e);             //入栈
SElemType Pop();                    //出栈,删除栈顶元素并返回其值,否则返回ERROR
SElemType GetTop(LinkStack s);      //返回栈顶元素
void StackTraverse(LinkStack s);    //从栈底向栈顶访问每个元素

int main()
{
    s = InitStack();
    SElemType e,ch[15];

    puts("请输入要入栈的字符串:");
    // scanf("%s",ch1);  //遇到空格会停止输入
    gets(ch);  //可以输入空格
    for(int i=0;i<strlen(ch);i++){
        printf("正在存入第 %d 个字符:%c\n",i+1,ch[i]);
        Push(ch[i]);  //入栈
    }
    printf("您的输入为(逆序):");
    StackTraverse(s);  //逆序访问每个元素

    e = GetTop(s); //返回栈顶元素
    printf("栈顶的元素为:%c\n",e);
    printf("栈的长度为:%d\n",StackLength(s));  //栈长

    printf("出栈元素为:");
    while(!StackEmpty(s)){  //如果栈不为空就一直出栈
        e = Pop();
        printf("%c",e);
    }
    printf("\n------------------------\n");

    //重新输入,测试清空栈
    puts("请输入要入栈的字符串:");
    gets(ch);
    for(int i=0;i<strlen(ch);i++){
        printf("正在存入第 %d 个字符:%c\n",i+1,ch[i]);
        Push(ch[i]);  //入栈
    }
    printf("您的输入为(逆序):");
    StackTraverse(s);
    s = ClearStack(s);  //清空栈
    printf("执行后的结果:");
    StackTraverse(s);

    DestroyStack(s);  //销毁栈
    return 0;
}

//1. 初始化
LinkStack InitStack()
{
    LinkStack s = NULL;
    printf("初始化链栈成功!\n");
    return s;
}

//2. 销毁栈函数
void DestroyStack(LinkStack s)
{
    LinkStack t;
    while(s != NULL){
        t = s;
        s = s->next;
        free(t);
    }
    printf("已销毁链栈!\n");
}

//3. 清除栈
LinkStack ClearStack(LinkStack s)
{
    s = NULL;   //直接将头指针(栈顶)置为空
    printf("栈已清空!\n");
    return s;
}

//4. 判断是否为空栈,是返回1,否 返回0
int StackEmpty(LinkStack s)
{
    if(s == NULL)
        return 1;
    else
        return 0;
}

//5. 返回栈的长度
int StackLength(LinkStack s)
{
    int i=0;
    LinkStack t=s;
    while(!StackEmpty(t)){
        t=t->next;
        i++;
    }
    free(t);
    return(i);
}

//6. 入栈
void Push(SElemType e)
{
    StackNode *p;
    p = (LinkStack)malloc(sizeof(StackNode));  //生成新结点
    if(p != NULL){
        p->data = e; //给新结点赋值
        p->next = s; //将新结点插入栈顶
        s = p; //s本身就指向栈顶,所以直接修改栈顶指针为p(p就是最后一个元素)
    }
    // printf("入栈成功!\n");
}

//7. 出栈,删除栈顶元素并返回其值
SElemType Pop()
{
    SElemType e;
    StackNode *p; 
    e = s->data;  //返回删除的元素
    p = s;        //用于临时保存要删除的元素
    s = s->next;  //栈顶往前挪一位,看似是s->next,但实际上是指栈顶的前一个元素,因为链栈中指针的顺序为an->a1,单链表是a1->an
    free(p);      //删除原本栈顶的元素
    return e;
}

//8. 返回栈顶元素
SElemType GetTop(LinkStack s)
{
    if(s!=NULL)
        return s->data;
    printf("栈为空!\n");
}

//9. 从栈顶向栈底访问每个元素(逆序,顺序输出的话可以建立双向循环链表)
void StackTraverse(LinkStack s)
{
    StackNode *p = s;
    if(s == NULL)
    {
        printf("栈为空!\n");
        return;
    }
    while(p!=NULL){
        printf("%c",p->data);
        p = p->next;
    }
    printf("\n");
}

运行结果

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值