• 用双向链表实现一个栈


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

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

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

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


    好的,看一下头文件吧。

    #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.
    ");
    		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
    ",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


    (完)



  • 相关阅读:
    MVC模式在Java Web应用程序中的实例分析
    设计模式
    实现xxxxxxx系统六大质量属性战术
    阅读了《大型网站技术架构:核心原理与案例分析》,分析XX系统如何增加相应的功能,提高系统的可用性和易用性
    淘宝系统质量属性分析
    《架构漫谈》读后感
    软件架构师架构设计过程是什么?
    《架构之美》阅读笔记06
    《架构之美》阅读笔记05
    《架构之美》阅读笔记04
  • 原文地址:https://www.cnblogs.com/longintchar/p/5224436.html
Copyright © 2020-2023  润新知