双向带环带头结点的链表实现栈

1. 数据结构

    利用带头结点带环的结点实现栈的相关操作.因此, 每一个结点包括了一个前驱, 一个后继, 还有一个数据成员

typedef char DLinkStackType;

typedef struct DLinkStack
{
    DLinkStackType data;
    struct DLinkStack* next;
    struct DLinkStack* prev;
}DLinkStack;
2. 初始化

    初始化即就是先给对应的结点申请一块内存, 然后将结点的数据成员置为 0 (个人所好), 然后将头结点的前驱后继依次指向空.

void DLinkStackInit(DLinkStack** stack)
{
    if(stack == NULL || *stack == NULL)
    {
        return;//非法输入
    }

    *stack = (DLinkStack*)malloc(sizeof(DLinkStack));
    (*stack) -> next = *stack;
    (*stack) -> prev = *stack;
    (*stack) -> data = 0;
}

这里写图片描述

3. 入栈

    将每一个结点从链表的尾部插入,即先创建一个新结点, 然后修改新结点和最后一个结点的指向, 将新结点插入链表, 然后修改头结点和新结点的指向, 便实现了入栈操作

void DLinkStackPush(DLinkStack* stack, DLinkStackType value)
{
    if(stack == NULL)
    {
        return;
    }
    DLinkStack* new_node = CreatNewNode(value);
    DLinkStack* prev = stack -> prev;
    prev -> next = new_node;
    new_node -> prev = prev;
    new_node -> next = stack;
    stack -> prev = new_node;
}

这里写图片描述

4. 出栈

    将每一个结点链表的尾部删除, 即修改倒数第二个结点和头结点的指向, 然后将倒数第一个结点删除, 这样便可以完成出栈

void DLinkStackPop(DLinkStack* stack)
{
    if(stack == NULL)
    {
        return;//非法输入
    }
    if(stack -> next == stack)
    {
        return;//空栈
    }
    DLinkStack* to_delete = stack -> prev;
    DLinkStack* prev = to_delete -> prev;
    //stack vs prev
    stack -> prev = prev;
    prev -> next = stack;
    DLinkStackNodeDestroy(to_delete);
    to_delete = NULL;
}

这里写图片描述

5. 创建结点
DLinkStack* CreatNewNode(DLinkStackType value)
{
    DLinkStack* new_node = (DLinkStack*)malloc(sizeof(DLinkStack));
    new_node -> data = value;
    new_node -> next = NULL;
    new_node -> prev = NULL;
    return new_node;
}
6. 取栈顶元素

    每次将头结点的下一个结点的数据返回, 即就完成了取栈顶元素

int DLinkStackGetFront(DLinkStack* stack, DLinkStackType* value)
{
    if(stack == NULL)
    {
        return -1;//非法输入
    }
    if(stack -> next == stack)
    {
        return -1;//空栈
    }
    *value = (stack -> prev) -> data;
    return 0;
}

这里写图片描述

7. 销毁栈

    从链表的第一个结点(stack -> next)开始, 依次删除每一个结点, 直到最后一个结点, 同时不要忘记将头结点(傀儡结点)也删除


void DLinkStackDestroy(DLinkStack** stack)
{
    if(stack == NULL)
    {
        return;//非法输入
    }
    if((*stack) -> prev == *stack)
    {
        DLinkStackNodeDestroy(*stack);
        *stack = NULL;
    }
    DLinkStack* next; 
    DLinkStack* to_delete;
    int i = DLinkStackSize(*stack);
    for(; i > 0; i--)
    {
        to_delete = (*stack) -> next;
        next = to_delete -> next;
        (*stack) -> next = next;
        next -> prev = *stack;
        DLinkStackNodeDestroy(to_delete);
        to_delete = NULL;
    }
    DLinkStackNodeDestroy(*stack);
    *stack = NULL;
}

这里写图片描述
    如有错误,还望大家能够随时提出, 大家共同进步

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值