c语言栈区循环,c语言之————有头循环双链表实现栈存储

栈的原理是先进的后出来

1、链表的实现

dlist.h

/*

*dlist.h

*描述:

*有头循环双表

*Data:

*2014-07-21

*/

#pragma once

#include

#include

#include

struct node_info

{

struct node_info *prev;

struct node_info *next;

char par[]; /*0长数组,不占空间*/

};

struct list_info

{

struct node_info head;

/*

* 头插

*/

void (*add)(struct list_info *,size_t data_size,const void *data_entry);

/*

* 尾插

*/

void (*add_tail)(struct list_info *,size_t data_size,const void *data_entry);

/*

* 得到第一个数据

*/

void (*get)(struct list_info *,size_t data_size,void *data_entry);

/*

* 获得最后一个数据

*/

void (*get_tail)(struct list_info *,size_t data_size, void *data_entry);

/*

* 删除节点

*/

void (*del)(struct list_info *,struct node_info *);

/*

* 判断节点是否为空

*/

int (*isempty)(struct list_info *);

};

void list_init(struct list_info*);

void list_destroy(struct list_info*);

#define PAR(node,type) ((type*)node->par)

#define list_for_each(info, cur) \

for (cur = (info)->head.next; \

(cur) != &(info)->head; \

cur = (cur)->next)

#define list_for_each_safe(info, cur, tmp) \

for (cur = (info)->head.next, tmp = (cur)->next; \

(cur) != &(info)->head; \

cur = tmp, tmp = (tmp)->next)

dlist.c

/*

*dlist.c

*

*/

#include "dlist.h"

static void list_add(struct list_info *info,size_t data_size,const void *data_entry)

{

struct node_info *new_node = (struct node_info *)malloc(sizeof(struct node_info) + data_size);

memcpy(new_node->par,data_entry,data_size);

new_node->prev = &info->head;

new_node->next = info->head.next;

info->head.next = new_node;

new_node->next->prev = new_node;//info->head.next->prev = new_node;

}

static void list_add_tail(struct list_info *info,size_t data_size,const void *data_entry)

{

struct node_info *new_node = (struct node_info *)malloc(sizeof(struct node_info) + data_size);

memcpy(new_node->par,data_entry,data_size);

new_node->prev = info->head.prev;

new_node->next = &info->head;

info->head.prev->next = new_node;

info->head.prev = new_node;//new_node->prev->next = new_node;

}

static void list_get(struct list_info *info,size_t data_size,void *data_entry)

{

memcpy(data_entry, info->head.next->par, data_size);

}

static void list_get_tail(struct list_info *info,size_t data_size,void *data_entry)

{

memcpy(data_entry, info->head.prev->par, data_size);

}

static void list_del(struct list_info *info,struct node_info *node)

{

node->prev->next = node->next;

node->next->prev = node->prev;

node->next = node;

node->prev = node;

free(node);

}

static int list_isempty(struct list_info *info)

{

//return info->head.prev == &info->head;

return info->head.next == &info->head;

}

void list_init(struct list_info *info)

{

info->head.prev = &info->head;

info->head.next = &info->head;

info->add = list_add;

info->add_tail = list_add_tail;

info->get = list_get;

info->get_tail = list_get_tail;

info->del = list_del;

info->isempty = list_isempty;

}

void list_destroy(struct list_info *info)

{

struct node_info *cur = NULL;

struct node_info *tmp = NULL;

list_for_each_safe(info, cur, tmp)

{

info->del(info, cur);

}

}

2、栈的实现

stack.h

/*

* stack.h

*

*/

#pragma once

#include "dlist.h"

struct stack_info

{

struct list_info list;

/*

* 入栈:

* 通过把数据头插入链表中

*/

void (*push)(struct stack_info *,size_t size,const void *data_entry);

/*

* 出栈:

* 获得链表中的第一个数据,并把它从链表中删除

*/

int (*pop)(struct stack_info *,size_t size,void *data_entry);

/*

* 设置栈顶指针:

* 把链表中的第一个数据设置为栈顶

*/

int (*top)(struct stack_info *,size_t size,void *data_entry);

/*

* 判断栈是否为空栈:

*

*/

int (*isempty)(struct stack_info *);

};

struct stack_info* stack_init(struct stack_info *);

void stack_destroy(struct stack_info *);

stack.c

/*

* stack.c

*

*/

#include "stack.h"

static void stack_push(struct stack_info *info,size_t size,const void *data_entry)

{

info->list.add(&info->list,size,data_entry);

}

static int stack_top(struct stack_info *info,size_t size,void *data_entry)

{

/*

* 栈为空就退出

*/

if(info->isempty(info))

{

return -1;

}

/*

* 如果栈不为空,就获得链表的第一个数据

*/

info->list.get(&info->list,size,data_entry);

return 0;

}

static int stack_pop(struct stack_info *info,size_t size,void *data_entry)

{

/*

* 如果没有栈顶数据就不能进行出栈操作,退出

*/

if(info->top(info,size,data_entry) < 0)

{

return -1;

}

else

{

info->list.del(&info->list,info->list.head.next);

return 0;

}

}

static int stack_isempty(struct stack_info *info)

{

return info->list.isempty(&info->list);

}

struct stack_info *stack_init(struct stack_info *info)

{

list_init(&info->list);

info->push = stack_push;

info->pop = stack_pop;

info->isempty = stack_isempty;

info->top = stack_top;

return info;

}

void stack_destroy(struct stack_info *info)

{

list_destroy(&info->list);

}

3、测试代码

test.c

/*

* test.c

*

*/

#include "stack.h"

struct data_info

{

const char*name;

size_t age;

};

int main()

{

struct stack_info stack;

struct data_info s[] = {

{"jack",20},

[1] = {

.name = "marry",

.age = 22

},

[2] = {"peter",21}

};

stack_init(&stack);

size_t i = 0;

for(i = 0; i < sizeof(s)/sizeof(struct data_info);i ++)

{

stack.push(&stack,sizeof(struct data_info),s + i);

}

if(stack.isempty(&stack))

{

printf("stack is empty!\n");

}

else

{

printf("stack is not empty!\n");

}

struct data_info tmp;

if(stack.top(&stack,sizeof(struct data_info),&tmp))

printf("no top data!\n");

else

{

printf("Top data is : name %s , age is %d \n",tmp.name,tmp.age);

}

stack_destroy(&stack);

printf("After destroy stack ... \n");

if(stack.isempty(&stack))

{

printf("stack is empty!\n");

}

else

{

printf("stack is not empty!\n");

}

return 0;

}

4、Makfile

all:test

test:test.o dlist.o stack.o

gcc -o $@ $^

test.o:test.c

gcc -c test.c

dlist.o:dlist.c

gcc -c dlist.c

stack.o:stack.c

gcc -c stack.c

clean:

rm *.o test

5、运行结果

stack is not empty!

Top data is : name peter , age is 21

After destroy stack ...

stack is empty!


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部