用双向链表实现一个栈

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

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

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

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


好的,看一下头文件吧。

#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


(完)



原文地址:https://www.cnblogs.com/longintchar/p/5224436.html