zoukankan      html  css  js  c++  java
  • 用双向链表实现一个栈

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

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

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

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


    好的,看一下头文件吧。

    #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


    (完)



  • 相关阅读:
    C语言 realloc为什么要有返回值,realloc返回值具体解释/(解决随意长度字符串输入问题)。
    opencv中的vs框架中的Blob Tracking Tests的中文注释。
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
  • 原文地址:https://www.cnblogs.com/longintchar/p/5224436.html
Copyright © 2011-2022 走看看