数据结构——链式栈

一、链式栈的管理结构体、节点设计

图解:

示例代码:

// 单向链表的节点设计
typedef struct node
{
    // 数据域
    int data;

    // 指针域
    struct node *next_p;

}node_t, *node_p;

// 链式栈的管理结构体设计
typedef struct link_stack
{
    node_p top_p;   // 链式栈的栈顶指针
    int    size;    // 链式栈的当前的元素个数

}link_stack_t, *link_stack_p;

二、初始化链式栈(空栈)

图解:

示例代码:

/**
  * @brief  初始化链式栈
  * @note   None	
  * @param  None
  * @retval 成功:返回指向这个链式栈管理结构体的指针
  *         失败:返回NULL
  */ 
link_stack_p LINK_STACK_Init(void) 
{
    // 1、申请内存空间
    link_stack_p p = malloc(sizeof(link_stack_t));
    bzero(p, sizeof(link_stack_t));

    // 2、给堆内存空间赋值
    if ( p!= NULL)
    {
        // a、初始化头节点
        p->top_p =  malloc(sizeof(node_t));
        bzero( p->top_p, sizeof(node_t));
        if ( p->top_p != NULL)
        {
            // 数据域不用赋值
            // 指针域
            p->top_p->next_p = NULL;
        }
        else
        {
            free(p);
            return NULL;
        }

        // b、链式栈的当前的元素个数(记录由几个数据节点)
        p->size = 0;
    }
    
    // 3、成功返回指向这个链式栈管理结构体的指针
    return p;
}

三、初始化数据节点,并且入栈

图解:

示例代码:

/**
  * @brief  初始化数据节点,并且入栈
  * @note   创建数据节点的功能也一并加入
  * @param  None
  * @retval 成功:返回0
  *         失败:返回非0
  */ 
int LINK_STACK_Push(link_stack_p p, int data) 
{
    // 1、创建数据节点
    node_p new_node = malloc(sizeof(node_t));
    bzero(new_node, sizeof(node_t));
    if ( new_node != NULL)
    {
        // 数据域赋值
        new_node->data = data;

        // 指针域
        new_node->next_p = NULL;
    }

    // 2、将这个数据节点进行入栈操作
    node_p head_node  = p->top_p;
    new_node->next_p  = head_node->next_p;
    head_node->next_p = new_node;

    // 3、更新size数据
    p->size++;

    // 4、成功返回0、
    return 0;
}

四、判断链式栈是否为空

示例代码:

/**
  * @brief  判断链表是否为空
  * @note   None	
  * @param  p:链式栈的管理结构体指针
  * @retval 如果链表为空:  返回true
  *         如果链表为非空:返回false
  */ 
bool LINK_STACK_IfEmpty(link_stack_p p)
{
    return (p->top_p->next_p == NULL);
}

五、遍历整个链式栈

图解:

示例代码:

/**
  * @brief  遍历整个链式表  
  * @note   None
  * @param  p:链式栈的管理结构体指针
  * @retval 成功:返回0
  *         失败:返回非0
  */ 
int LINK_STACK_ShowStack(link_stack_p p) 
{
    // 1、判断链表是否为空,是的话,返回-1
    if (LINK_STACK_IfEmpty(p))
        return -1;

    // 2、遍历整个链表,并逐个打印里面的数据
    node_p tmp_p = NULL;
    int    i     = 0;
    printf("================链式表中的数据====================\n\n");
    for (tmp_p = p->top_p->next_p, i = p->size-1; tmp_p != NULL;  tmp_p = tmp_p->next_p, i--)
    {
        printf("link_stack[%d] = %d\n", i, tmp_p->data);
    }

    printf("===================================================\n");

    // 3、成功返回0
    return 0;
}

六、出栈 --- 删除栈顶数据

图解:

示例代码:

/**
  * @brief  出栈 --- 删除数据节点
  * @note   None
  * @param  p:链式栈的管理结构体指针
  * @retval 成功:返回0
  *         失败:返回非0
*/ 
int LINK_STACK_Pop(link_stack_p p) 
{
    // 1、判断链式栈是否为空
    if (LINK_STACK_IfEmpty(p))  
        return -1;

    // 2、将栈顶数据删除
    node_p last_node  = p->top_p;
    node_p del_node   = last_node->next_p;
    node_p next_node  = del_node->next_p;
    
    last_node->next_p = next_node;
    free(del_node);

    // 3、将链式栈的数据节点个数减1
    p->size--;

    // 4、成功返回0
    return 0;
}

七、获取或修改栈顶数据

图解:

示例代码:

/**
  * @brief  获取或修改栈顶数据 --- 查改功能
  * @note   None
  * @param  p:    链式栈的管理结构体指针
  *         data: 
  * @retval 成功:返回读取的栈顶的数据
  *         失败:返回NULL
*/ 
int* LINK_STACK_GetTopData(link_stack_p p) 
{
    // 1、判断链式栈是否为空
    if (LINK_STACK_IfEmpty(p))  
        return NULL;

    // 2、成功返回栈顶数据的指针
    return &(p->top_p->next_p->data);
}

八、销毁整个链式栈

图解:

示例代码:

/**
  * @brief  销毁整个链式栈
  * @note   None
  * @param  p:链式栈的管理结构体指针
  * @retval 成功:返回0
  *         失败:返回非0
  */ 
int LINK_STACK_UnInit(link_stack_p p) 
{
    // 1、一个个删除并释放数据节点
    node_p tmp_p     = NULL;      // 是用来遍历的
    node_p last_node = p->top_p;
    node_p del_node  = last_node->next_p;
    node_p next_node = del_node->next_p;

    for (tmp_p= last_node;  tmp_p->next_p!=NULL; tmp_p=tmp_p->next_p) 
    {
        // a、删除节点并释放其内存
        last_node->next_p  = next_node;
        free(del_node);

        // b、轮回继续
        del_node  = next_node;
        next_node = next_node->next_p;
    }

    if (tmp_p->next_p==NULL)        // 最后还有一个数据节点,也将其删除并释放了
    {
        last_node->next_p  = next_node;
        free(del_node);
    }

    // 2、释放头节点和链式栈的管理结构体
    free(last_node);
    free(p);

    
    // 3、成功返回0
    return 0;
}

以上的内容属于我的课后笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值