数据结构--链式堆栈

1. 简介

栈是限制在一段进行插入操作和删除操作的线性表(俗称堆栈),允许进行操作的一端称为“栈顶”,另一固定端称为“栈底”,当栈中没有元素称为“空栈”。特点:先进后出(FILO)。

2. 源码

[LinkStack.c]

/*
*********************************************************************************************************
* @file     LinkStack.c
* @author   SY
* @version  V1.0.0
* @date     2016-9-2 10:16:49
* @IDE      V4.70.0.0
* @Chip     STM32F407VE
* @brief    链式堆栈源文件
*********************************************************************************************************
* @attention
*   栈是限制在一段进行插入操作和删除操作的线性表(俗称堆栈),允许进行操作的一端称为“栈顶”,
*   另一固定端称为“栈底”,当栈中没有元素称为“空栈”。特点:先进后出(FILO)。
*
* 
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private Includes
*********************************************************************************************************
*/
#include "utils.h"
#include "LinkStack.h"


/*
*********************************************************************************************************
*                                           Private define
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                           Private typedef
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private constants
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private macro
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private variables
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private function prototypes
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Private functions
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* Function Name : CreateLinkStack
* Description   : 创建链式堆栈(内存空间由内部提供、动态内存)
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
LINK_STACK_TypeDef *CreateLinkStack( void )
{
    /* 生成栈顶节点 */
    LINK_STACK_TypeDef *top = (LINK_STACK_TypeDef *)calloc(1,sizeof(LINK_STACK_TypeDef));
    if (top == NULL)
    {
        return NULL;
    }

    top->data = NULL;
    top->next = NULL;

    return top;
}

/*
*********************************************************************************************************
* Function Name : LinkStackIsEmpty
* Description   : 链式堆栈是否为空
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
DATA_STRUCT_STATUS_ENUM LinkStackIsEmpty( LINK_STACK_TypeDef *top )
{
    if (top == NULL)
    {
        return STATUS_DATA_STRUCT_UNDEFINED;
    }

    if (top->next == NULL)
    {
        return STATUS_DATA_STRUCT_TRUE;
    }
    else
    {
        return STATUS_DATA_STRUCT_FALSE;
    }
}

/*
*********************************************************************************************************
* Function Name : ClearLinkStack
* Description   : 清空链式堆栈
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void ClearLinkStack( LINK_STACK_TypeDef *top )
{
    if (top != NULL)
    {
        LINK_STACK_TypeDef *oldNode = NULL;

        while (top->next != NULL)
        {
            oldNode = top->next;
            top->next = oldNode->next;
            oldNode->next = NULL;

            if (oldNode->data != NULL)
            {
                free(oldNode->data);
                oldNode->data = NULL;
            }

            free(oldNode);
            oldNode = NULL;             
        }
    }
}

/*
*********************************************************************************************************
* Function Name : DestoryLinkStack
* Description   : 销毁链式堆栈
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void DestoryLinkStack( LINK_STACK_TypeDef **top )
{
    LINK_STACK_TypeDef *this = *top;

    if (this != NULL)
    {
        ClearLinkStack(this);

        /* 释放栈顶节点 */
        free(this);

        *top = NULL;
    }
}

/*
*********************************************************************************************************
* Function Name : PushLinkStack
* Description   : 入栈
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
DATA_STRUCT_STATUS_ENUM PushLinkStack( LINK_STACK_TypeDef *top, void *dataIn, uint32_t dataSize )
{
    if (top == NULL)
    {
        return STATUS_DATA_STRUCT_UNDEFINED;
    }

    /* 增加新节点 */
    LINK_STACK_TypeDef *pNode = (LINK_STACK_TypeDef *)calloc(1,sizeof(LINK_STACK_TypeDef));
    if (pNode == NULL)
    {
        return STATUS_DATA_STRUCT_FALSE;
    }
    pNode->next = top->next;    
    top->next = pNode;

    /* 存储用户数据 */
    pNode->data = (void *)calloc(1,dataSize);
    if (pNode->data == NULL)
    {
        return STATUS_DATA_STRUCT_FALSE;
    }   
    memcpy(pNode->data,dataIn,dataSize);

    return STATUS_DATA_STRUCT_TRUE;
}

/*
*********************************************************************************************************
* Function Name : PopLinkStack
* Description   : 出栈
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
DATA_STRUCT_STATUS_ENUM PopLinkStack( LINK_STACK_TypeDef *top, void *dataOut, uint32_t dataSize )
{
    if (top == NULL)
    {
        return STATUS_DATA_STRUCT_UNDEFINED;
    }

    if (LinkStackIsEmpty(top) == STATUS_DATA_STRUCT_TRUE)
    {
        return STATUS_DATA_STRUCT_FALSE;
    }

    LINK_STACK_TypeDef *oldNode = top->next;    
    top->next = oldNode->next;
    oldNode->next = NULL;

    DATA_STRUCT_STATUS_ENUM isDataOK = STATUS_DATA_STRUCT_FALSE;
    if (oldNode->data != NULL)
    {
        memcpy(dataOut,oldNode->data,dataSize);
        free(oldNode->data);
        oldNode->data = NULL;
        isDataOK = STATUS_DATA_STRUCT_TRUE;
    }

    free(oldNode);
    oldNode = NULL;

    return isDataOK;
}

/*
*********************************************************************************************************
* Function Name : GetLinkStackElement
* Description   : 获取链式堆栈元素
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
DATA_STRUCT_STATUS_ENUM GetLinkStackElement( LINK_STACK_TypeDef *top, void *dataOut, uint32_t dataSize )
{
    if (top == NULL)
    {
        return STATUS_DATA_STRUCT_UNDEFINED;
    }

    if (LinkStackIsEmpty(top) == STATUS_DATA_STRUCT_TRUE)
    {
        return STATUS_DATA_STRUCT_FALSE;
    }

    DATA_STRUCT_STATUS_ENUM isDataOK = STATUS_DATA_STRUCT_FALSE;
    LINK_STACK_TypeDef *oldNode = top->next;    
    if (oldNode->data != NULL)
    {
        memcpy(dataOut,oldNode->data,dataSize);
        isDataOK = STATUS_DATA_STRUCT_TRUE;
    }

    return isDataOK;
}

/*
*********************************************************************************************************
* Function Name : TraverseLinkStack
* Description   : 遍历链式堆栈
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void TraverseLinkStack( LINK_STACK_TypeDef *top, void *dataOut, uint32_t dataSize,\
        void (*show_CallBack)( void *dataOut ) )
{
    LINK_STACK_TypeDef stack = *top;
    LINK_STACK_TypeDef *pNode = stack.next;

    while (pNode != NULL)
    {
        memcpy(dataOut,pNode->data,dataSize);

        if (show_CallBack)
        {
            show_CallBack(dataOut);
        }

        pNode = pNode->next;
    }
}

/************************ (C) COPYRIGHT STMicroelectronics **********END OF FILE*************************/
[LinkStack.h]

/*
*********************************************************************************************************
* @file     LinkStack.h
* @author   SY
* @version  V1.0.0
* @date     2016-9-2 10:16:49
* @IDE      V4.70.0.0
* @Chip     STM32F407VE
* @brief    链式堆栈头文件
*********************************************************************************************************
* @attention
*
* 
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Define to prevent recursive inclusion
*********************************************************************************************************
*/
#ifndef __LINKSTACK_H
#define __LINKSTACK_H

/*
*********************************************************************************************************
*                                           Exported Includes
*********************************************************************************************************
*/



/*
*********************************************************************************************************
*                                           Exported define
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Exported types
*********************************************************************************************************
*/
typedef struct tagLINK_STACK_TypeDef
{
    void *data;
    struct tagLINK_STACK_TypeDef *next;
}LINK_STACK_TypeDef;


/*
*********************************************************************************************************
*                                           Exported constants
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Exported macro
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Exported variables
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           Exported functions
*********************************************************************************************************
*/
LINK_STACK_TypeDef *CreateLinkStack( void );
DATA_STRUCT_STATUS_ENUM LinkStackIsEmpty( LINK_STACK_TypeDef *top );
void ClearLinkStack( LINK_STACK_TypeDef *top );
void DestoryLinkStack( LINK_STACK_TypeDef **top );
DATA_STRUCT_STATUS_ENUM PushLinkStack( LINK_STACK_TypeDef *top, void *dataIn, uint32_t dataSize );
DATA_STRUCT_STATUS_ENUM PopLinkStack( LINK_STACK_TypeDef *top, void *dataOut, uint32_t dataSize );
DATA_STRUCT_STATUS_ENUM GetLinkStackElement( LINK_STACK_TypeDef *top, void *dataOut, uint32_t dataSize );
void TraverseLinkStack( LINK_STACK_TypeDef *top, void *dataOut, uint32_t dataSize,\
        void (*show_CallBack)( void *dataOut ) );

#endif
/************************ (C) COPYRIGHT STMicroelectronics **********END OF FILE*************************/

备注:


1、本文以链表形式实现堆栈,使用动态内存存储链表节点及数据域。
2、采用泛型编程思想,不限制数据类型。数据可以是基本数据类型也可以是复合数据类型。

3.测试

[main.c]

/*
*********************************************************************************************************
* Function Name : PrintSeqQueue
* Description   : 打印顺序队列
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void PrintSeqQueue( void *data )
{
    uint8_t *temp = data;

    printf("%d\r\n",*temp);
}

/*
*********************************************************************************************************
* Function Name : TestLinkStack
* Description   : 测试链式堆栈
* Input         : None
* Output        : None
* Return        : None
*********************************************************************************************************
*/
void TestLinkStack( void )
{
    LINK_STACK_TypeDef *pHead = CreateLinkStack();
    if (pHead == NULL)
    {
        printf("内存分配失败!\r\n");

        return;
    }

    {
        for (uint8_t i=1; i<=3; ++i)
        {
            PushLinkStack(pHead, &i, sizeof(i));
        }

        uint8_t dataBuff = 0;

        printf("----- STATR -----\r\n");
        TraverseLinkStack(pHead, &dataBuff, sizeof(dataBuff), PrintSeqQueue);
        printf("----- E N D -----\r\n\r\n");
    }

    {
        uint8_t dataBuff = 0;
        PopLinkStack(pHead,&dataBuff, sizeof(dataBuff));
        printf("出栈元素:%d\r\n",dataBuff);

        printf("----- STATR -----\r\n");
        TraverseLinkStack(pHead, &dataBuff, sizeof(dataBuff), PrintSeqQueue);
        printf("----- E N D -----\r\n\r\n");
    }
}

打印结果:


—– STATR —–
3
2
1
—– E N D —–

出栈元素:3
—– STATR —–
2
1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值