栈之链栈

目录

  1. 链栈的简介
  2. 举例以及详细分析
  3. 代码块
  4. 测试结果

链栈的简介

链栈则没有上溢的限制,它就象是一条一头固定的链子,可以在活动的一头自由地增加链环(结点)而不会溢出,链栈不需要在头部附加头结点,因为栈都是在头部进行操作的,如果加了头结点,等于要在头结点之后的结点进行操作,反而使算法更复杂,所以只要有链表的头指针就可以了。


举例以及详细分析

**栈可以采用链式存储结构表示,采用这种结构表示的栈简称为链栈。
在一个链栈中,栈底就是链表的最后一个节点,而栈顶总是链表的第一个节点。**
这里写图片描述


代码块

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
//定义结点结构体
typedef struct Node
{
    int data;    //内容
    struct Node * pNext; //指向下一结点的指针
} NODE, *PNODE;   //NODE等价于struct Node, PNODE等价于struct Node *
//定义栈的结构体
typedef struct Stack
{
    PNODE pTop;    //栈顶结点
    PNODE pBottom;   //栈底结点
} STACK, *PSTACK;   //STACK等价于struct Stack, PSTACK等价于struct Stack *
//函数声明
void initStack(PSTACK pStack);    //对栈进行初始化的函数
void pushStack(PSTACK pStack, int val);  //入栈的函数
bool popStack(PSTACK pStack, int * pVal);//出栈的函数,*pVal用来保存出栈的元素内容
void traverseStack(PSTACK pStack);   //遍历栈的函数
bool isEmpty(PSTACK pStack);    //判断栈是否为空的函数
void clearStack(PSTACK pStack);   //清空栈的函数
int main(void)
{
    STACK stack;   //定义一个栈变量,STACK等价于struct Stack
    int val;    //用来保存出栈的内容
    initStack(&stack);  //调用栈的初始化函数
    pushStack(&stack, 10); //调用入栈的函数
    pushStack(&stack, 20);
    pushStack(&stack, 30);
    pushStack(&stack, 50);
    traverseStack(&stack); //调用遍历栈的函数
    //调用出栈的函数
    if (popStack(&stack, &val))
        printf("出栈成功,出栈的元素值为:%d\n", val);
    else
        printf(" 出栈失败!");
    //调用清空栈的函数
    clearStack(&stack);
    traverseStack(&stack); //调用遍历栈的函数
    system("pause");
    return 0;
}

void initStack(PSTACK pStack)
{
    //创建一个空结点,让pTop指向它
    pStack->pTop = (PNODE)malloc(sizeof(NODE));
    if (NULL != pStack->pTop)
    {
        //将pBottom也指向空节点
        pStack->pBottom = pStack->pTop;
        //清空空结点的指针域
        pStack->pTop->pNext = NULL;
    }
    else      //如果内存分配失败
    {
        printf("内存分配失败!程序退出!\n");
        exit(-1);
    }
    return;
}

void pushStack(PSTACK pStack, int val)
{
    //动态创建一个新结点
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    //设置新结点的数据域的值
    pNew->data = val;
    //将新结点的指针域指向之前建的空节点
    pNew->pNext = pStack->pTop;   //pStack->pTop不能换成pStack->pBottom
    //pTop指向新的结点
    pStack->pTop = pNew;
    return;
}

bool popStack(PSTACK pStack, int *pVal)
{
    if (isEmpty(pStack))
    {
        return false;
    }
    else
    {
        //先保存栈顶元素的地址,然后将pTop指向下一元素,最后释放之前栈顶元素的内存
        PNODE rNode = pStack->pTop;
        *pVal = rNode->data;
        pStack->pTop = rNode->pNext;
        free(rNode);
        rNode = NULL;
        return true;
    }
}

void traverseStack(PSTACK pStack)
{
    //将栈顶赋给一个临时结点,因为在遍历栈的时候不能销毁栈
    PNODE pNode = pStack->pTop;
    //循环遍历栈,直到栈底
    while (pStack->pBottom != pNode)
    {
        printf("%d  ", pNode->data);
        pNode = pNode->pNext;
    }
    printf("\n");
    return;
}

bool isEmpty(PSTACK pStack)
{
    if (pStack->pTop == pStack->pBottom)
        return true;
    else
        return false;
}

void clearStack(PSTACK pStack)
{ //栈为空,则退出该函数
    if (isEmpty(pStack))
    {
        return;
    }
    else
    {
        //两个结点指针变量用来释放栈中元素的内存
        PNODE p = pStack->pTop;
        PNODE q = NULL;
        //循环释放内存
        while (p != pStack->pBottom)
        {
            q = p->pNext;
            free(p);
            p = q;
        }
        //将栈顶和栈底指向同一个指针域为空的结点
        pStack->pTop = pStack->pBottom;
        return;
    }
}

测试结果

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值