栈的操作(入栈、出栈)之二:链栈

栈操作原则

使用栈操作数据,必须遵循“先入后出”的原则;

栈操作之链栈

链栈是用链表实现栈的存储结构,链表头部作为栈顶,链表尾部为栈底(单链表);
在这里插入图片描述

入栈

写入数据时,实际是对链表做“头插”操作,空链表时,头指针head指向null;新进数据插入链表头部,头指针head指向当前链表头部;以此类推,这种操作即为入栈(压栈);
在这里插入图片描述

出栈

读出数据时,实际是删除当前链表的头部(首元节点),将头指针head指向新的链表头部(原首元节点的下一节点,成为当前首元节点),以此类推,这种操作即为出栈(弹栈);

在这里插入图片描述

代码实现

在这段代码中,主要实现:
1.创建链表数据结构,初始化为空链表;
2.入栈操作,压入8个数据;
3.出栈操作,弹出2个数据,栈中剩余最先入栈的6个数据;
4.打印各个过程的情况;
5.在CMD中运行查看结果;

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

// 创建链表的数据结构
typedef struct list_stack
{
    int data;
    struct list_stack *next;
} list_stack;

// 链栈入栈操作,head为当前链栈栈顶指针,val为入栈的值
list_stack *push(list_stack *head, int val)
{
    // 创建新节点,并分配内存
    list_stack *p = (list_stack *)malloc(sizeof(list_stack));

    p->data = val;
    // 建立当前节点与头指针head之前所指节点的关系(头插)
    p->next = head;
    // 使头指针head指向当前新插入节点
    head = p;
    printf("push elem %d\r\n", head->data);
    printf("current head elem is : %d\r\n", head->data);

    return head;
}

list_stack *pop(list_stack *head)
{
    // 如果head指向不为空,可进行出栈操作
    if (head != NULL)
    {   
        // 头指针head当前指向表头节点,定义指针p指向表头节点
        list_stack *p = head;
        // 使头指针head指向下一个节点,即删除head之前所指节点(单链表)
        head = head->next;
        //打印出栈元素,即被删除节点的值(p所指节点)
        printf("pop elem %d\r\n", p->data);
        //释放内存
        free(p);
        //如果head指向非空,打印当前head所指节点的值
        if(head != NULL)
        {
            printf("current head elem is : %d\r\n", head->data);
        }
        //如果head指向为空,打印提示信息
        else
        {
            printf("pop fail! no more elem!\r\n");
        }
    }
    else
    {
        printf("stack is empty!\r\n");
    }

    return head;
}

// 正向遍历链表,打印出链表节点值
void show_list_in_order(list_stack *head)
{
    // 链表不为空,执行遍历
    if (head != NULL)
    {
        // head指向链表头部,初始化使p从链表头部开始
        list_stack *p = head;

        printf("list stack from head to tail is:\r\n");
        while (p->next != NULL)
        {
            printf("%d\r\n", p->data);
            p = p->next;
        }
        // 打印出链表尾部节点值
        printf("%d\r\n", p->data);
    }
    else
    {
        printf("print fail! stack is empty!\r\n");
    }
}

int main(void)
{
    int i = 0;
    int j = 0;

    // 初始化头指针head指向为空,即链表为空
    list_stack *head = NULL;

    // 压栈操作,并打印栈内元素值
    printf("push stack:\r\n");
    for (i = 0; i < 8; i++)
    {
        head = push(head, i);
    }
    show_list_in_order(head);

    // 出栈操作,并打印栈内元素值
    printf("\npop stack:\r\n");
    for (j = 0; j < 2; j++)
    {
        head = pop(head);
    }
    show_list_in_order(head);
}

CMD运行结果

在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值