前面我们已经造好了一个轮子——双向链表,那么我们可以利用这个轮子做一个栈。

入栈:我们采用链表的头插

获得栈顶的元素:把头部元素拷贝到用户数据区

出栈:先把头部的元素拷贝到用户数据区,然后删除这个节点

好的,看一下头文件吧。

#pragma once
#include "dlist.h"struct stack_info {struct dlist_info *dlist;// 双向链表的指针int (*push)(struct stack_info *info, const  void *data, size_t size);//入栈int (*top)(struct stack_info *info,void *data, size_t size);//获得栈顶的元素int (*pop)(struct stack_info *info,void *data, size_t size);//出栈int (*is_empty)(struct stack_info *info);
};void stack_init(struct stack_info *info);
void stack_destroy(struct stack_info *info);

接下来看实现。

static int stack_push(struct stack_info *info, const  void *data, size_t size)
{info->dlist->add_head(info->dlist, data, size);return 0;
}

是不是很简单呢?直接头插就可以了。

static int stack_is_empty(struct stack_info *info)
{return  dlist_is_empty(info->dlist);
}
static int stack_top(struct stack_info *info,void *data, size_t size)
{if (stack_is_empty(info)) {return -1;}else{memcpy(data, info->dlist->head->next->data, size);}return 0;
}

top方法,注意,这个方法只会得到栈顶元素的值,并不会删除栈顶的元素。

static int stack_pop(struct stack_info *info,void *data, size_t size)
{if (stack_top(info, data, size) < 0) {return -1;// means empty}else{info->dlist->del(info->dlist->head->next);}return 0;
}

pop方法,不用多说。

构造和析构:

void stack_init(struct stack_info *info)
{info->dlist = (struct dlist_info *)malloc(sizeof(struct dlist_info));if (info->dlist != NULL) {dlist_init(info->dlist);}else{printf("stack initialize failed.\n");return ;}info->push = stack_push;info->pop = stack_pop;info->top = stack_top;info->is_empty = stack_is_empty;
}void stack_destroy(struct stack_info *info)
{dlist_destroy(info->dlist);free(info->dlist);
}

最后我们看一下单元测试

void print_student(void* data)
{struct student *p = (struct student *)(data);printf("Name: %15s  Age:%d\n",p->name,p->age);}START_TEST(case_2)
{struct student students[] = {{"WangDong",18},{"LiuMing",19},{"SunYazhou",21},{"QingYun",27}};struct stack_info stack;stack_init(&stack);struct student stu_tmp;ck_assert_msg(stack.is_empty(&stack)==1);int i = 0;for(;i<(sizeof(students)/sizeof(students[0]));++i)stack.push(&stack,students+i,sizeof(students[0]));while(stack.is_empty(&stack)!=1){stack.pop(&stack,&stu_tmp,sizeof(students[0]));print_student(&stu_tmp);}}
END_TEST

简单的测一下pop和push,结果如下:

Running suite(s): stack_(using_dlist)

Name:         QingYun  Age:27

Name:       SunYazhou  Age:21

Name:         LiuMing  Age:19

Name:        WangDong  Age:18

100%: Checks: 1, Failures: 0, Errors: 0

(完)

用双向链表实现一个栈相关推荐

  1. 栈与队列4——用一个栈实现另一个栈的排序

    题目 一个栈A的元素类型为整形,仅使用一个栈B,来实现栈A从栈顶到栈底元素是从大到小的顺序. 思路 原来的栈为stack,申请的栈为help,当前stack的栈顶元素记为cur 如果cur小于help ...

  2. 栈与队列3——用递归和栈操作逆序一个栈

    题目 一个栈依次压入1,2,3:此时栈顶到栈底元素分别为:3,2,1:将栈反转,使得栈顶到栈底元素为:1,2,3,仅限递归函数,并且不能使用其他数据结构 思路 使用两个函数reverse和getAnd ...

  3. 创建一个栈存储结构,并且写入一些对栈的基本的操作

    什么是栈:简单的说就是一个容器,一个瓶子,我们向瓶子里面放糖果,当想吃糖果的时候,将瓶子里的糖果再倒出来.我们要实现的就是怎样创建一个瓶子,并且怎样很容易的向里面添加糖果,向吃糖果的时候可以拿出来,自 ...

  4. python 判断括号是否匹配_使用Python实现一个栈判断括号是否平衡

    栈(Stack)在计算机领域是一个被广泛应用的集合,栈是线性集合,访问都严格地限制在一段,叫做顶(top). 举个例子,栈就想一摞洗干净的盘子,你每次取一个新盘子,都是放在这一摞盘子的最上头,当你往里 ...

  5. 如何仅用递归函数和栈操作逆序一个栈——你要先用stack实现,再去改成递归——需要对递归理解很深刻才能写出来...

    /**  * 如何仅用递归函数和栈操作逆序一个栈  * 题目:  * 一个栈依次压入1,2,3,4,5,那么从栈顶到栈底分别为5,4,3,2,1.  * 将这个栈转置后,从栈顶到栈底为1,2,3,4, ...

  6. 用一个栈实现另一个栈的排序

    要求: 在一个栈中元素的类型为整型,现在想将该栈从栈顶到栈底按从大到小的顺序排序,只许申请一个栈,除此之外,可以申请其他变量,但是不能申请额外的数据结构 解题思路: 待排序的栈stack, 辅助栈he ...

  7. 如何仅用递归函数和栈操作逆序一个栈

    [题目]​ 一个栈依次压入1.2.3.4.5,那么从栈顶到栈底分别为5.4.3.2.1.将这个栈转置后,从栈顶到栈底为1.2.3.4.5,也就是实现栈中元素的逆序,但是只能用递归函数来实现,不能用其他 ...

  8. 如何用JavaScript手动实现一个栈

    什么是栈(Stack) 栈是一种遵从后进先出(LIFO)原则的有序集合. 新添加的或待删除的元素都保存在栈的末尾,称为栈顶,另一端叫栈底. 在栈里,新元素都靠近栈顶,旧元素都接近栈底 现实中的例子 在 ...

  9. 两个栈实现一个队列,两个队列实现一个栈

    题目:用两个栈实现一个队列,用两个队列实现一个栈. 首先要了解栈和队列这两种数据结构各自的特点,栈是一种后入先出(Last In First Out,LIFO)的数据结构,队列是一种先进先出(Firs ...

最新文章

  1. 在Clojure中使用class
  2. mysql 的select语句_MySQLSELECT语句_MySQL
  3. UGUI全面实践教程
  4. 【Android 性能优化】布局渲染优化 ( CPU 渲染优化 | 减少布局的嵌套 | 测量布局绘制时间 | OnFrameMetricsAvailableListener | 布局渲染优化总结 )
  5. Qt Creator 最实用的快捷操作
  6. 总结3:IDEA中使用${pageContext.request.contextPath}填写路径时出错
  7. MySQL 如何查看表的存储引擎
  8. 删除分卷php逻辑,Linux LVM(逻辑卷管理)删除详解
  9. 建议阅读的投资经典55本
  10. 计算机应用基础作业4第一次,《计算机应用基础》第一次作业题目、答案
  11. 【JZOJ4847】【NOIP2016提高A组集训第5场11.2】夕阳
  12. 高级渗透之VBS调用WMI接口
  13. Ubuntu系统关闭搜狗输入法Shift切换中英文
  14. MySQL下执行*.sql文件
  15. Wilson定理证明
  16. gsoc 任务_黑客#GSOC:如何获得现实生活经验并支持开源
  17. 公务员面试题——人际关系
  18. JS总结——获取元素的各种高度宽度
  19. 使用ThinkJs搭建微信中控服务
  20. 美国计算机硕士学校,美国计算机硕士不同学校申请难度大盘点(下篇)

热门文章

  1. NYOJ 664 数字整除
  2. scrollBy与scrollTo的区别与用法
  3. Docker 单机网络
  4. codevs 1066 引水入城(DFS+DP)
  5. IDA Pro的patch插件 KeyPatch
  6. 页面间参数值传递含“%”的处理方法
  7. Linux下gcc入门
  8. 我的秋招之路(开篇)
  9. 正则表达式匹配C++代码实现
  10. 命令行模式下的后向引用替换