diff --git a/Chapter11/ds/line/stack/arr/Makefile b/Chapter11/ds/line/stack/arr/Makefile new file mode 100644 index 0000000..a7681ed --- /dev/null +++ b/Chapter11/ds/line/stack/arr/Makefile @@ -0,0 +1,31 @@ +# 方便起见一般都会先定义编译器链接器 +CC = gcc +LD = gcc + +# 正则表达式表示目录下所有.c文件,相当于:SRCS = main.c a.c b.c +SRCS = $(wildcard *.c) + +# OBJS表示SRCS中把列表中的.c全部替换为.o,相当于:OBJS = main.o a.o b.o +OBJS = $(patsubst %c, %o, $(SRCS)) + +# 可执行文件的名字 +TARGET = main + +# .PHONE伪目标,具体含义百度一下一大堆介绍 +.PHONY:all clean + +# 要生成的目标文件 +all: $(TARGET) + +# 第一行依赖关系:冒号后面为依赖的文件,相当于Hello: main.o a.o b.o +# 第二行规则:$@表示目标文件,$^表示所有依赖文件,$<表示第一个依赖文件 +$(TARGET): $(OBJS) + $(LD) -o $@ $^ + +# 上一句目标文件依赖一大堆.o文件,这句表示所有.o都由相应名字的.c文件自动生成 +%.o:%.c + $(CC) -c $^ + +# make clean删除所有.o和目标文件 +clean: + rm -f $(OBJS) $(TARGET) diff --git a/Chapter11/ds/line/stack/arr/main.c b/Chapter11/ds/line/stack/arr/main.c new file mode 100644 index 0000000..2b8f8dd --- /dev/null +++ b/Chapter11/ds/line/stack/arr/main.c @@ -0,0 +1,41 @@ +#include +#include + +#include "sqstack.h" + +int main() +{ + datatype arr[] = {19, 23, 0, 45, 67}; + sqstack *st; + int i; + + st = st_create(); + if (NULL == st) + exit(1); + + for (i = 0; i < sizeof(arr) / sizeof(*arr); i++) + st_push(st, &arr[i]); + + st_travel(st); + + datatype tmp; + while (0 == st_pop(st, &tmp)) + { + printf("POP:%d\n", tmp); + } + +#if 0 + datatype tmp = 1; + int ret; + + ret = st_push(st, &tmp); + if (0 != ret) + printf("st_push failed.\n"); + else + st_travel(st); + + st_destroy(st); +#endif + + exit(0); +} \ No newline at end of file diff --git a/Chapter11/ds/line/stack/arr/sqstack.c b/Chapter11/ds/line/stack/arr/sqstack.c new file mode 100644 index 0000000..d10927d --- /dev/null +++ b/Chapter11/ds/line/stack/arr/sqstack.c @@ -0,0 +1,72 @@ +#include +#include + +#include "sqstack.h" + +sqstack *st_create(void) +{ + sqstack *st; + + st = malloc(sizeof(*st)); + if (NULL == st) + return NULL; + + st->top = -1; + + return st; +} + +int st_isempty(sqstack *st) +{ + return (-1 == st->top); +} + +int st_push(sqstack *st, datatype *data) +{ + if (MAXSIZE - 1 == st->top) + return -1; + + st->data[++st->top] = *data; + + return 0; +} + +/* 取出栈顶元素 */ +int st_pop(sqstack *st, datatype *data) +{ + if (st_isempty(st)) + return -1; + + *data = st->data[st->top--]; + + return 0; +} + + +/* 查看栈顶元素 */ +int st_top(sqstack *st, datatype *data) +{ + if (st_isempty(st)) + return -1; + + *data = st->data[st->top]; + + return 0; +} + +void st_travel(sqstack *st) +{ + if (st_isempty(st)) + return; + + int i; + + for (i = 0; i <= st->top; i++) + printf("%d ", st->data[i]); + printf("\n"); +} + +void st_destroy(sqstack *st) +{ + free(st); +} diff --git a/Chapter11/ds/line/stack/arr/sqstack.h b/Chapter11/ds/line/stack/arr/sqstack.h new file mode 100644 index 0000000..f36cc58 --- /dev/null +++ b/Chapter11/ds/line/stack/arr/sqstack.h @@ -0,0 +1,30 @@ +#ifndef SQSTACK_H__ +#define SQSTACK_H__ + +#define MAXSIZE 5 + +typedef int datatype; + +typedef struct node_st +{ + datatype data[MAXSIZE]; + int top; +} sqstack; + +sqstack *st_create(void); + +int st_isempty(sqstack *); + +int st_push(sqstack *, datatype *); + +/* 取出栈顶元素 */ +int st_pop(sqstack *, datatype *); + +/* 查看栈顶元素 */ +int st_top(sqstack *, datatype *); + +void st_travel(sqstack *); + +void st_destroy(sqstack *); + +#endif \ No newline at end of file diff --git a/Chapter11/ds/line/stack/list/Makefile b/Chapter11/ds/line/stack/list/Makefile new file mode 100644 index 0000000..a7681ed --- /dev/null +++ b/Chapter11/ds/line/stack/list/Makefile @@ -0,0 +1,31 @@ +# 方便起见一般都会先定义编译器链接器 +CC = gcc +LD = gcc + +# 正则表达式表示目录下所有.c文件,相当于:SRCS = main.c a.c b.c +SRCS = $(wildcard *.c) + +# OBJS表示SRCS中把列表中的.c全部替换为.o,相当于:OBJS = main.o a.o b.o +OBJS = $(patsubst %c, %o, $(SRCS)) + +# 可执行文件的名字 +TARGET = main + +# .PHONE伪目标,具体含义百度一下一大堆介绍 +.PHONY:all clean + +# 要生成的目标文件 +all: $(TARGET) + +# 第一行依赖关系:冒号后面为依赖的文件,相当于Hello: main.o a.o b.o +# 第二行规则:$@表示目标文件,$^表示所有依赖文件,$<表示第一个依赖文件 +$(TARGET): $(OBJS) + $(LD) -o $@ $^ + +# 上一句目标文件依赖一大堆.o文件,这句表示所有.o都由相应名字的.c文件自动生成 +%.o:%.c + $(CC) -c $^ + +# make clean删除所有.o和目标文件 +clean: + rm -f $(OBJS) $(TARGET) diff --git a/Chapter11/ds/line/stack/list/llist.c b/Chapter11/ds/line/stack/list/llist.c new file mode 100644 index 0000000..1190181 --- /dev/null +++ b/Chapter11/ds/line/stack/list/llist.c @@ -0,0 +1,130 @@ +#include +#include +#include + +#include "llist.h" + +LLIST *llist_create(int initsize) +{ + LLIST *new; + + new = malloc(sizeof(*new)); // !!! 不是sizeof(initsize),也不是new,是*new + if (NULL == new) + return NULL; + + new->size = initsize; + new->head.prev = &new->head; + new->head.next = &new->head; + + return new; +} + +int llist_insert(LLIST *ptr, const void *data, int mode) +{ + struct llist_node_st *newnode; + + newnode = malloc(sizeof(*newnode) + ptr->size); // -4 + if (NULL == newnode) + return -1; + + memcpy(newnode->data, data, ptr->size); + + if (LLIST_FORWARD == mode) + { + newnode->prev = &ptr->head; + newnode->next = ptr->head.next; + } + else if (LLIST_BACKWARD == mode) + { + newnode->prev = ptr->head.prev; + newnode->next = &ptr->head; + } + else // error + { + return -3; + } + + // !!! 妙啊 + newnode->next->prev = newnode; + newnode->prev->next = newnode; + + return 0; +} + +static struct llist_node_st *find_(LLIST *ptr, const void *key, llist_cmp *cmp) +{ + struct llist_node_st *cur; + + for (cur = ptr->head.next; cur != &ptr->head; cur = cur->next) + { + if (0 == cmp(key, cur->data)) + break; + } + + return cur; // 找不到的时候,返回的cur就是ptr,返回NULL +} + +void *llist_find(LLIST *ptr, const void *key, llist_cmp *cmp) +{ + struct llist_node_st *node; + node = find_(ptr, key, cmp); + if (node == &ptr->head) + return NULL; + + return node->data; +} + +int llist_delete(LLIST *ptr, const void *key, llist_cmp *cmp) +{ + struct llist_node_st *node; + + node = find_(ptr, key, cmp); + if (node == &ptr->head) + return -1; + + // !!! + node->prev->next = node->next; + node->next->prev = node->prev; + free(node); + return 0; +} + +int llist_fetch(LLIST *ptr, const void *key, llist_cmp *cmp, void *data) +{ + struct llist_node_st *node; + + node = find_(ptr, key, cmp); + if (node == &ptr->head) + return -1; + + node->next->prev = node->prev; + node->prev->next = node->next; + + if (data != NULL) + memcpy(data, node->data, ptr->size); + + free(node); + + return 0; +} + +void llist_travel(LLIST *ptr, llist_op *op) +{ + struct llist_node_st *cur; + + for (cur = ptr->head.next; cur != &ptr->head; cur = cur->next) + op(cur->data); +} + +void llist_destroy(LLIST *ptr) +{ + struct llist_node_st *cur, *next; + + for (cur = ptr->head.next; cur != &ptr->head; cur = next) + { + next = cur->next; + free(cur); + } + + free(ptr); +} diff --git a/Chapter11/ds/line/stack/list/llist.h b/Chapter11/ds/line/stack/list/llist.h new file mode 100644 index 0000000..48457e4 --- /dev/null +++ b/Chapter11/ds/line/stack/list/llist.h @@ -0,0 +1,39 @@ +#ifndef LLIST_H__ +#define LLIST_H__ + +#define LLIST_FORWARD 1 +#define LLIST_BACKWARD 2 + +// !!! 变长结构体 +struct llist_node_st +{ + struct llist_node_st *prev; + struct llist_node_st *next; + // data要放在最后 + char data[1]; // 占位符,数据的起始。C99才只是[0] +}; + +typedef struct +{ + int size; + struct llist_node_st head; +} LLIST; + +typedef void llist_op(const void *); +typedef int llist_cmp(const void *, const void *); + +LLIST *llist_create(int initsize); + +int llist_insert(LLIST *ptr, const void *data, int mode); + +void *llist_find(LLIST *ptr, const void *key, llist_cmp *); + +int llist_delete(LLIST *, const void *key, llist_cmp *); + +int llist_fetch(LLIST *, const void *key, llist_cmp *, void *data); + +void llist_travel(LLIST *ptr, llist_op *op); + +void llist_destroy(LLIST *ptr); + +#endif diff --git a/Chapter11/ds/line/stack/list/main.c b/Chapter11/ds/line/stack/list/main.c new file mode 100644 index 0000000..72312b6 --- /dev/null +++ b/Chapter11/ds/line/stack/list/main.c @@ -0,0 +1,55 @@ +#include +#include + +#include "stack.h" + +#define NAMESIZE 32 + +struct score_st +{ + int id; + char name[NAMESIZE]; + int math; + int chinese; +}; + +static int print_s(void *record) +{ + struct score_st *r = record; + + printf("%d %s %d %d\n", r->id, r->name, r->math, r->chinese); +} + +int main() +{ + STACK *st; + struct score_st tmp; + int i, ret; + + st = stack_create(sizeof(struct score_st)); + if (NULL == st) + exit(1); + + for (i = 0; i < 7; i++) + { + tmp.id = i; + snprintf(tmp.name, NAMESIZE, "stu%d", i); + tmp.math = rand() % 100; + tmp.chinese = rand() % 100; + + if (stack_push(st, &tmp)) + exit(1); + } + + while (1) + { + ret = stack_pop(st, &tmp); + if (-1 == ret) + break; + print_s(&tmp); + } + + stack_destroy(st); + + exit(0); +} \ No newline at end of file diff --git a/Chapter11/ds/line/stack/list/stack.c b/Chapter11/ds/line/stack/list/stack.c new file mode 100644 index 0000000..10950c3 --- /dev/null +++ b/Chapter11/ds/line/stack/list/stack.c @@ -0,0 +1,29 @@ +#include + +#include "stack.h" + +LLIST *stack_create(int initsize) +{ + return llist_create(initsize); +} + +int stack_push(STACK *ptr, const void *data) +{ + return llist_insert(ptr, data, LLIST_FORWARD); +} + +static int always_match(const void *p1, const void *p2) +{ + return 0; +} + +int stack_pop(STACK *ptr, void *data) +{ + // !!! 假接口 + return llist_fetch(ptr, (void *)0, always_match, data); +} + +void stack_destroy(STACK *ptr) +{ + llist_destroy(ptr); +} \ No newline at end of file diff --git a/Chapter11/ds/line/stack/list/stack.h b/Chapter11/ds/line/stack/list/stack.h new file mode 100644 index 0000000..630f5e4 --- /dev/null +++ b/Chapter11/ds/line/stack/list/stack.h @@ -0,0 +1,16 @@ +#ifndef STACK_H__ +#define STACK_H__ + +#include "llist.h" + +typedef LLIST STACK; + +STACK *stack_create(int); + +int stack_push(STACK *, const void *data); + +int stack_pop(STACK *, void *data); + +void stack_destroy(STACK *); + +#endif \ No newline at end of file