也没想象中那么神秘的数据结构-后来居上的“栈”(链栈)

概念

关于栈的相关内容,在之前的文章已经详细介绍过了,请参见《也没想象中那么神秘的数据结构-后来居上的“栈”》,本文主要将链栈相关内容。

链式栈:采用链式储存结构的栈,使用单链表来实现。将单链表的第一个结点为栈顶结点,栈总是指向栈顶结点。

核心

栈的结构:栈总是指向栈顶节点,栈底节点指向NULL,节点与节点之间通过指针一环扣一环连接起来。

入栈:在栈顶节点之前插入新节点操作,插入的时候注意节点指针指向的改变。

出栈:删除当前栈顶节点,并将之前栈顶节点指向的下一个节点作为栈顶节点的操作,弹出的时候注意节点指针指向的改变。

示例

★包含头文件stack_list.h和源文件stack_list.c(均已验证通过)。

 stack_list.h

/**
 * @Filename : stack_list.h
 * @Revision : $Revision: 1.0 $
 * @Author : Feng(微信公众号:不只会拍照的程序猿)
 * @Description : 链栈示例
**/

#ifndef __STACK_LIST_H__
#define __STACK_LIST_H__

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

#define MAX_SIZE 10    /* 栈最大元素个数 */

/* 栈节点元素定义 */
struct t_node{
    int data;                           /* 元素值 */
    struct t_node *p_next;     /* 指向下一个元素 */
};

/* 栈空间定义 */
struct t_stack{
    struct t_node *p_top;      /* 栈顶元素 */
    int size;                          /* 元素个数 */
};

/**
 * @初始化栈
 * @p_stack:栈
**/
void stack_init(struct t_stack *p_stack);

/**
 * @清除栈
 * @p_stack:栈
**/
void stack_deinit(struct t_stack *p_stack);

/**
 * @判断栈是否已满
 * @p_stack:栈
 * @返回1表示已满,0表示未满
**/
int stack_is_full(const struct t_stack *p_stack);

/**
 * @判断栈是否已空
 * @p_stack:栈
 * @返回1表示已空,0表示未空
**/
int stack_is_empty(const struct t_stack *p_stack);

/**
 * @获取栈元素个数
 * @p_stack:栈
 * @返回元素个数
**/
int stack_get_size(const struct t_stack *p_stack);

/**
 * @入栈操作
 * @p_stack:栈      data:待插入元素
 * @返回1表示成功,0表示失败
**/
int stack_push(struct t_stack *p_stack, int data);

/**
 * @出栈操作
 * @p_stack:栈      p_data:保存出栈元素
 * @返回1表示成功,0表示失败
**/
int stack_pop(struct t_stack *p_stack, int *p_data);

/**
 * @获取栈顶元素
 * @p_stack:栈      p_data:保存栈顶元素
 * @返回1表示成功,0表示失败
**/
int stack_get_top(const struct t_stack *p_stack, int *p_data);

/**
 * @打印栈元素内容
 * @p_stack:栈
**/
void stack_print(const struct t_stack *p_stack);

#endif

 stack_list.c

/**
 * @Filename : stack_list.c
 * @Revision : $Revision: 1.0 $
 * @Author : Feng(微信公众号:不只会拍照的程序猿)
 * @Description : 链栈示例
**/

#include "stack_list.h"

/**
 * @初始化栈
 * @p_stack:栈
**/
void stack_init(struct t_stack *p_stack)
{
    p_stack->size = 0;
    p_stack->p_top = NULL;
}

/**
 * @清除栈
 * @p_stack:栈
**/
void stack_deinit(struct t_stack *p_stack)
{
    struct t_node *p_tmp = NULL, *p_node = p_stack->p_top;

    while(p_node) {
        p_tmp = p_node;
        p_node = p_node->p_next;
        free(p_tmp);    
    }
    p_stack->size = 0;
} 

/**
 * @判断栈是否已满
 * @p_stack:栈
 * @返回1表示已满,0表示未满
**/
int stack_is_full(const struct t_stack *p_stack)
{
    return (p_stack->size >= MAX_SIZE);
}

/**
 * @判断栈是否已空
 * @p_stack:栈
 * @返回1表示已空,0表示未空
**/
int stack_is_empty(const struct t_stack *p_stack)
{
    return (p_stack->size == 0);
}

/**
 * @获取栈元素个数
 * @p_stack:栈
 * @返回元素个数
**/
int stack_get_size(const struct t_stack *p_stack)
{
    return (p_stack->size);
}

/**
 * @创建节点
 * @data:元素值
 * @返回节点地址,NULL表示失败
**/
static struct t_node *creat_node(int data)
{
    struct t_node *p_node = (struct t_node *)malloc(sizeof(struct t_node));

    if (p_node == NULL)
        return NULL;

    p_node->data = data; 
    p_node->p_next = NULL;

    return  p_node;  
}

/**
 * @入栈操作
 * @p_stack:栈      data:待插入元素
 * @返回1表示成功,0表示失败
**/
int stack_push(struct t_stack *p_stack, int data)
{
    struct t_node *p_node = NULL;

    if (p_stack->size >= MAX_SIZE)
        return 0;

    if ((p_node = creat_node(data)) == NULL)
        return 0;

    p_node->p_next = p_stack->p_top;
    p_stack->p_top = p_node;    

    p_stack->size++;

    return 1;
}

/**
 * @出栈操作
 * @p_stack:栈      p_data:保存出栈元素
 * @返回1表示成功,0表示失败
**/
int stack_pop(struct t_stack *p_stack, int *p_data)
{
    struct t_node *p_node = NULL;

    if (p_stack->size == 0)
        return 0;

    p_node = p_stack->p_top;
    p_stack->p_top = p_stack->p_top->p_next;

    *p_data = p_node->data;
    free(p_node);
    p_stack->size--;

    return 1;
}

/**
 * @获取栈顶元素
 * @p_stack:栈      p_data:保存栈顶元素
 * @返回1表示成功,0表示失败
**/
int stack_get_top(const struct t_stack *p_stack, int *p_data)
{
    if (p_stack->size == 0)
        return 0;

    *p_data = p_stack->p_top->data;

    return 1;
}

/**
 * @打印栈元素内容
 * @p_stack:栈
**/
void stack_print(const struct t_stack *p_stack)
{
    struct t_node *p_node = p_stack->p_top;

    while(p_node) {
        printf("%d ", p_node->data);
        p_node = p_node->p_next;   
    }

    printf("\n");
}

/**
 * @链栈测试代码
**/
int main(void)
{
    int data;
    struct t_stack my_stack;

    stack_init(&my_stack);      /* 初始化栈,此时为空栈 */   
    printf("the stack is %s\n", stack_is_empty(&my_stack) ? "empty" : "not empty");
    printf("---------------------------------------\n");

    /* 压栈,栈:25 41 16 7 8 19 22,元素个数为7 */    
    stack_push(&my_stack, 25);
    stack_push(&my_stack, 41);
    stack_push(&my_stack, 16);
    stack_push(&my_stack, 7);
    stack_push(&my_stack, 8);
    stack_push(&my_stack, 19);
    stack_push(&my_stack, 22);   
    printf("the size of stack is: %d\n", stack_get_size(&my_stack));
    stack_print(&my_stack);
    printf("---------------------------------------\n");

    /* 压栈35 38 11 22(栈已满,入栈失败),栈:25 41 16 7 8 19 22 35 38 11,个数10 */
    stack_push(&my_stack, 35);
    stack_push(&my_stack, 38);
    stack_push(&my_stack, 11);
    stack_push(&my_stack, 22);
    printf("the size of stack is: %d\n", stack_get_size(&my_stack));
    stack_print(&my_stack);
    printf("the stack is %s\n", stack_is_full(&my_stack) ? "full" : "not full");
    printf("---------------------------------------\n");

    /* 栈顶元素为11,第一次出栈11,第二次出栈38,栈:25 41 16 7 8 19 22 35,个数8 */
    if (stack_get_top(&my_stack, &data))
        printf("the top stack data is: %d\n", data);    
    if (stack_pop(&my_stack, &data))
        printf("the pop stack data is: %d\n", data);    
    if (stack_pop(&my_stack, &data))
        printf("the pop stack data is: %d\n", data);   
    printf("the size of stack is: %d\n", stack_get_size(&my_stack));
    stack_print(&my_stack);
    printf("---------------------------------------\n");

    /* 清除栈,个数0 */
    stack_deinit(&my_stack);
    printf("the size of stack is: %d\n", stack_get_size(&my_stack));

    return 0;
}

结论

feng:stack$ gcc -o stack_list stack_list.c
feng:stack$ ./stack_list
the stack is empty
---------------------------------------
the size of stack is: 7
22 19 8 7 16 41 25 
---------------------------------------
the size of stack is: 10
11 38 35 22 19 8 7 16 41 25 
the stack is full
---------------------------------------
the top stack data is: 11
the pop stack data is: 11
the pop stack data is: 38
the size of stack is: 8
35 22 19 8 7 16 41 25 
---------------------------------------
the size of stack is: 0
feng:stack$ 

本示例仅为链栈示例,公众号也提供顺序栈示例《也没想象中那么神秘的数据结构-后来居上的“栈”》,以及栈的典型应用示例。

关注

更多精彩内容,请关注微信公众号:不只会拍照的程序猿,本人致力分享linux、设计模式、C语言、嵌入式、编程相关知识,也会抽空分享些摄影相关内容,同样也分享大量摄影、编程相关视频和源码,另外你若想要本文章源码请关注公众号:不只会拍照的程序猿,后台回复:数据结构源码,也可点击此处下载

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不只会拍照的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值