动态栈

动态栈基于单链表实现,与静态栈(数组)相比,提供了更灵活的存储方式。栈的操作遵循先进后出的原则,动态栈利用这一特性在数据处理中发挥重要作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态栈

  1. 栈:动态栈和静态栈
    ->动态栈的基本内核是单链表(离散存储)(砍掉单链表的一些操作[对单链表增加一些限制条件]就可以形成栈);
    ->静态栈的基本内核是一维数组(连续存储)。

  2. 栈的特点:数据元素遵从’先进后出’的规则

/*
    ********************动态栈******************
*/
# include <stdio.h>
# include <malloc.h>//包含malloc()函数的声明
# include <stdlib.h>//包含exit()函数的声明

//自定义节点结构体
typedef struct Node
{
    int data;
    struct Node * pNext;
}NODE, * PNODE; 
//自定义栈结构体
typedef struct Stack
{
    PNODE pTop;
    PNODE pBottom;
}STACK, * PSTACK;

//declare function
void InitStack(PSTACK pS);
void PushStack(PSTACK pS,int val);
void TraverseStack(PSTACK pS);
int  GetTop(PSTACK pS);
PNODE PopStack(PSTACK pS);
bool EmptyStack(PSTACK pS);
void GetDelTop(PSTACK pS,int * pVal);
int GetLength(PSTACK pS);

int main(void)
{
    STACK S;//建立栈S
    int val;
//初始化栈
    InitStack(&S);
//压栈
    PushStack(&S,1);
    PushStack(&S,2);
    PushStack(&S,3);
    PushStack(&S,4);
    printf("Output(traverse):");
    TraverseStack(&S);//遍历栈[遍历相当于指全部浏览一遍并不进行任何操作]
    printf("stack length: %d\n\n",GetLength(&S));
//读栈顶元素
    val = GetTop(&S);
    printf("pTop value: %d\n",val);
//读取并删除栈顶元素
    printf("get and delete pTop:\n");
    GetDelTop(&S,&val);
    printf("pTop value: %d\n",val);
    printf("stack length: %d\n\n",GetLength(&S));
//出栈
    printf("popstack:\n");
    PopStack(&S);
    printf("stack length: %d\n\n",GetLength(&S));

    return 0;
}
//initialize stack
void InitStack(PSTACK pS)
{
    pS->pTop = (PNODE)malloc(sizeof(NODE));//建立一个新节点(作用:让pTop和pBottom同时指向这个节点)
    if(NULL == pS->pTop)
    {
        printf("ALLOCATION IS FAILED!\n");
        exit(-1);//内存分配不成功直接退出程序
    }
    else
    {
        pS->pBottom = pS->pTop;
        pS->pBottom->pNext = NULL;//初始化pBottom指针指向的节点的指针域为空(类似于单链表的头结点(它没任何作用只是便于链表操作))
    }

    return;
}
//push stack
void PushStack(PSTACK pS,int val)
{
    PNODE pNew = (PNODE)malloc(sizeof(NODE));

    pNew->data = val;
    pNew->pNext = pS->pTop;//链接新节点和栈顶指针
    pS->pTop = pNew;//栈顶指针指向新节点

    return;
}
//traverse stack
void TraverseStack(PSTACK pS)
{
    PNODE p = pS->pTop;//必须新建一个指针p(指向栈顶指针指向的存储单元),不能直接操作栈顶指针因为会改变栈(遍历操作是不会改动栈的)

    while(p != pS->pBottom)
    {
        printf("%-3d",p->data);
        p = p->pNext;   
    }
    printf("\n");

    return;
}
//determine whether stack is empty or not
bool EmptyStack(PSTACK pS)
{
    if(pS->pTop == pS->pBottom)//起初建立并初始化栈的时候满足其中一个条件'pS->pTop == pS->pBottom'
    {
        return true;
    }
    else
    {
        return false;
    }
}
//get the value of pTop
int  GetTop(PSTACK pS)//因为要读栈顶元素的值所以应该返回一个数据类型是'int'的值
{
    if(EmptyStack(pS))
    {
        printf("STACK IS EMPTY!\n");
        return 0;
    }
    else
    {
        return pS->pTop->data;
    }
}
//pop stack
PNODE PopStack(PSTACK pS)//出栈指的是移出整个节点所以声明的数据类型是'PNODE'
{
    if(EmptyStack(pS))
    {
        printf("STACK IS EMPTY!\n");
        return NULL;
    }
    else
    {
        PNODE p = pS->pTop;
        pS->pTop = pS->pTop->pNext;
        free(p);//释放指针p指向的存储单元里的数据
        p = NULL;//清空变量名为p的存储单元
        return pS->pTop;
    }
}
//get and delete pTop
void GetDelTop(PSTACK pS,int * pVal)//将获取的值存入指针pVal指向的存储单元中
{
    if(EmptyStack(pS))
    {
        printf("STACK IS EMPTY!\n");
    }
    else
    {
        * pVal = GetTop(pS);
        PopStack(pS);
    }

    return;
}
//get the length of stack
int GetLength(PSTACK pS)
{
    int cnt = 0;//代表栈的有效长度
    PNODE p = pS->pTop;//必须加一个指向‘pS->pTop’的指针p否则‘pS->pTop’会随着操作改变从而整个‘栈’会改变

    if(EmptyStack(pS))
    {
        printf("STACK IS EMPTY!\n");
        return 0;
    }
    else
    {
        while(p != pS->pBottom)
        {
            ++cnt;
            p = p->pNext;//指针指向下一个节点
        }
        return cnt;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值