栈的链表实现(C语言)

 源码文件地址 :http://download.csdn.net/detail/mcu_tian/9530628

由前面:http://blog.csdn.net/mcu_tian/article/details/51493081所述

链表实现的栈在操作过程中频繁的pop和push会伴随着频繁的malloc和free,伴随着很大的系统开销。

基于此,在此实现中,通过实现一个空闲节点链表,将pop之后的链表节点不释放,而是放入空闲链表freeNodePtr中

当栈进行push操作的时候,先从空闲节点链表中中取出空闲节点加入栈链表中,若是空闲链表中,没有节点,则调用malloc,申请内存节点。

栈是否空栈只要判断指向栈顶指针是否为空即可。

实现的操作有pop、push、reset、isempty、create、dispose等基本函数,实现了链表节点 stacknode,以及栈的结构体ListIntStack等,具体如下

结构体

链表元素节点结构体

<pre name="code" class="cpp">struct StackIntNode //元素节点
{
    struct StackIntNode *pre;
    struct StackIntNode *next;
    int num;//元素节点值
};
typedef struct StackIntNode *StackNodePtr;
typedef struct StackIntNode StackNode;


//栈结构体
 
struct ListIntStack//栈结构体
{
    StackNodePtr topPtr;//栈顶
    StackNodePtr freeNodePtr;//空闲链表
    int lenght;//栈元素个数
};
typedef struct ListIntStack *ListStack;


 
 

函数

创建栈函数

该函数的主要功能为栈创建一个结构体对象,初始化后返回结构体对象指针。

<pre name="code" class="cpp">ListStack CreateListStack(int num) //创建链表栈
{
    StackNodePtr tmpPtr;
    ListStack s;
    s = (ListStack)malloc(sizeof(struct ListIntStack));
    if(s == NULL)
    {
        printf("creat list stact falied");
        return NULL;
    }
    s->topPtr = NULL;
    s->freeNodePtr = NULL;
    s->lenght = 0;
    return s;
}

 

释放栈函数

该函数的主要功能是1:链表节点释放,链表节点在栈链表中和free两个链表中  2:释放栈的结构体对象

void DisposeListStack(ListStack *ls)
{
    StackNodePtr tmpPtr;
    int count_num = 0; //计算一共有多少个节点被释放

    tmpPtr = (*ls)->topPtr;
    while(tmpPtr != NULL)  //释放栈链表
    {
        (*ls)->topPtr = (*ls)->topPtr->pre;
        free(tmpPtr);
        tmpPtr = (*ls)->topPtr;
        ++count_num;
    }

    tmpPtr = (*ls)->freeNodePtr;//释放free链表
    while(tmpPtr != NULL)
    {
        (*ls)->freeNodePtr = (*ls)->freeNodePtr->next;

        free(tmpPtr);

        tmpPtr = (*ls)->freeNodePtr;
        ++count_num;
    }

    free(*ls);
    (*ls) = NULL;
    printf("dispose count_num is %d\n",count_num);
}
是否为空栈

int IsListStackEmpty(ListStack ls)
{
     return ls->topPtr == NULL;
}

栈push操作函数

栈的push操作,先判断空闲链表上时候有空闲节点,若有,则从空闲链表中取下节点,或则调用malloc申请

int ListStackPush(ListStack ls,int *element)//成功返回1,否则为-1,element 指向的为入栈的数据的指针
{
    StackNodePtr tmp;
    if(ls->freeNodePtr != NULL)
    {
        tmp = ls->freeNodePtr;
        ls->freeNodePtr = ls->freeNodePtr->next;

        if(ls->freeNodePtr != NULL)
        {
            ls->freeNodePtr->pre = NULL;
        }
        tmp->num = *element;
        if(IsListStackEmpty(ls))
        {
            ls->topPtr = tmp;
            tmp->next = tmp->pre = NULL;
        }
        else
        {
            ls->topPtr->next = tmp;
            tmp->pre = ls->topPtr;
            ls->topPtr=ls->topPtr->next;
            tmp->next = NULL;
        }
    }
        else
        {

            tmp = malloc(sizeof(StackNode));
            if(tmp == NULL)
            {
                printf("malloc failed\n");
                return -1;
            }
            tmp->num = *element;
            if(ls->topPtr == NULL)
            {
                ls->topPtr = tmp;
                tmp->next = NULL;
                tmp->pre = NULL;
                return 1;
            }
            ls->topPtr->next = tmp;
            tmp->pre = ls->topPtr;
            tmp->next = NULL;

            ls->topPtr = ls->topPtr->next;

        }
    ++ls->lenght;
    return 1;
}
栈pop函数以及reset函数

该函数将栈链表总的栈顶元素取下来,放入到空闲链表中。

int ListstackPop(ListStack ls)//操作成功返回1.失败返回-1
{
    StackNodePtr tmpPtr;
    if(IsListStackEmpty(ls))
    {
        printf("list stack pop failed\n");
        return -1;
    }

    tmpPtr = ls->topPtr;
    ls->topPtr = ls->topPtr->pre;

    if(ls->topPtr != NULL)
    {
        ls->topPtr->next = NULL;
    }

    tmpPtr->pre = NULL;
    if(ls->freeNodePtr == NULL)
    {
        ls->freeNodePtr = tmpPtr;
    }
    else
    {
        ls->freeNodePtr->pre = tmpPtr;
        tmpPtr->next = ls->freeNodePtr;
        ls->freeNodePtr = ls->freeNodePtr->pre;
    }
      --ls->lenght;
    return 1;
}
//迭代调用pop,直到栈为空
int ListStackReset(ListStack ls)
{
    while(!IsListStackEmpty(ls))
    {
        if(ListstackPop(ls) != 1)
        {
            return -1;
        }
    }
    return 1;
}


取栈顶元素Top函数

读栈链表的栈顶元素

int ListStackTop(ListStack ls,int *element)//将栈顶的值,放入到element指针指向的变量中
{
    if(IsListStackEmpty(ls))
    {
        printf("Top is NULL\n");
        return -1;
    }
    *element = ls->topPtr->num;
    return 1;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值