From 9fd115d30b31d95a49e88a95419f9de0ba581c94 Mon Sep 17 00:00:00 2001 From: lzy Date: Wed, 17 Apr 2024 15:12:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=E5=92=8C=E9=93=BE=E5=BC=8F=E7=9A=84=E9=98=9F=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chapter11/ds/line/squeue/arr/Makefile | 31 ++++++ Chapter11/ds/line/squeue/arr/main.c | 39 ++++++++ Chapter11/ds/line/squeue/arr/queue.c | 72 ++++++++++++++ Chapter11/ds/line/squeue/arr/queue.h | 29 ++++++ Chapter11/ds/line/squeue/list/Makefile | 31 ++++++ Chapter11/ds/line/squeue/list/llist.c | 130 +++++++++++++++++++++++++ Chapter11/ds/line/squeue/list/llist.h | 39 ++++++++ Chapter11/ds/line/squeue/list/main.c | 56 +++++++++++ Chapter11/ds/line/squeue/list/queue.c | 26 +++++ Chapter11/ds/line/squeue/list/queue.h | 16 +++ 10 files changed, 469 insertions(+) create mode 100644 Chapter11/ds/line/squeue/arr/Makefile create mode 100644 Chapter11/ds/line/squeue/arr/main.c create mode 100644 Chapter11/ds/line/squeue/arr/queue.c create mode 100644 Chapter11/ds/line/squeue/arr/queue.h create mode 100644 Chapter11/ds/line/squeue/list/Makefile create mode 100644 Chapter11/ds/line/squeue/list/llist.c create mode 100644 Chapter11/ds/line/squeue/list/llist.h create mode 100644 Chapter11/ds/line/squeue/list/main.c create mode 100644 Chapter11/ds/line/squeue/list/queue.c create mode 100644 Chapter11/ds/line/squeue/list/queue.h diff --git a/Chapter11/ds/line/squeue/arr/Makefile b/Chapter11/ds/line/squeue/arr/Makefile new file mode 100644 index 0000000..a7681ed --- /dev/null +++ b/Chapter11/ds/line/squeue/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/squeue/arr/main.c b/Chapter11/ds/line/squeue/arr/main.c new file mode 100644 index 0000000..8b48f9e --- /dev/null +++ b/Chapter11/ds/line/squeue/arr/main.c @@ -0,0 +1,39 @@ +#include +#include + +#include "queue.h" + +int main() +{ + queue *sq; + datatype arr[] = {2, 34, 89, 12}; + int i; + + sq = qu_create(); + if (NULL == sq) + exit(1); + + for (i = 0; i < sizeof(arr) / sizeof(*arr); i++) + qu_enqueue(sq, &arr[i]); + + qu_travel(sq); + + datatype tmp; + qu_dequeue(sq, &tmp); + printf("DEQUEUE:%d\n", tmp); + +#if 0 + datatype tmp = 100; + int ret; + + ret = qu_enqueue(sq, &tmp); + if (-1 == ret) + printf("Queue is full!\n"); + else + qu_travel(sq); +#endif + + qu_destroy(sq); + + exit(0); +} \ No newline at end of file diff --git a/Chapter11/ds/line/squeue/arr/queue.c b/Chapter11/ds/line/squeue/arr/queue.c new file mode 100644 index 0000000..d1b3631 --- /dev/null +++ b/Chapter11/ds/line/squeue/arr/queue.c @@ -0,0 +1,72 @@ +#include +#include + +#include "queue.h" + + +queue *qu_create() +{ + queue *sq; + + sq = malloc(sizeof(*sq)); + if (NULL == sq) + return NULL; + + sq->head = 0; + sq->tail = 0; + + return sq; +} + +int qu_isempty(queue *sq) +{ + return (sq->head == sq->tail); +} + +int qu_enqueue(queue *sq, datatype *x) +{ + if ((sq->tail + 1) % MAXSIZE == sq->head) + return -1; + + sq->tail = (sq->tail + 1) % MAXSIZE; + sq->data[sq->tail] = *x; + + return 0; +} + +int qu_dequeue(queue *sq, datatype *x) +{ + if (qu_isempty(sq)) + return -1; + + sq->head = (sq->head + 1) % MAXSIZE; + *x = sq->data[sq->head]; + + return 0; +} + +void qu_travel(queue *sq) +{ + if (sq->head == sq->tail) + return; + + int i; + + i = (sq->head + 1) % MAXSIZE; + while (i != sq->tail) + { + printf("%d ", sq->data[i]); + i = (i + 1) % MAXSIZE; + } + printf("%d \n", sq->data[i]); +} + +void qu_clear(queue *sq) +{ + sq->head = sq->tail; +} + +void qu_destroy(queue *sq) +{ + free(sq); +} diff --git a/Chapter11/ds/line/squeue/arr/queue.h b/Chapter11/ds/line/squeue/arr/queue.h new file mode 100644 index 0000000..3632758 --- /dev/null +++ b/Chapter11/ds/line/squeue/arr/queue.h @@ -0,0 +1,29 @@ +#ifndef QUEUE_H__ +#define QUEUE_H__ + +#define MAXSIZE 5 + +typedef int datatype; + +typedef struct node_st +{ + datatype data[MAXSIZE]; + int head, tail; +} queue; + + +queue *qu_create(); + +int qu_isempty(); + +int qu_enqueue(queue *, datatype *); + +int qu_dequeue(queue *, datatype *); + +void qu_travel(queue *); + +void qu_clear(queue *); + +void qu_destroy(queue *); + +#endif \ No newline at end of file diff --git a/Chapter11/ds/line/squeue/list/Makefile b/Chapter11/ds/line/squeue/list/Makefile new file mode 100644 index 0000000..a7681ed --- /dev/null +++ b/Chapter11/ds/line/squeue/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/squeue/list/llist.c b/Chapter11/ds/line/squeue/list/llist.c new file mode 100644 index 0000000..1190181 --- /dev/null +++ b/Chapter11/ds/line/squeue/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/squeue/list/llist.h b/Chapter11/ds/line/squeue/list/llist.h new file mode 100644 index 0000000..48457e4 --- /dev/null +++ b/Chapter11/ds/line/squeue/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/squeue/list/main.c b/Chapter11/ds/line/squeue/list/main.c new file mode 100644 index 0000000..2468f07 --- /dev/null +++ b/Chapter11/ds/line/squeue/list/main.c @@ -0,0 +1,56 @@ +#include +#include + +#include "queue.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() +{ + QUEUE *qu; + struct score_st tmp; + int i, ret; + + qu = queue_create(sizeof(struct score_st)); + if (NULL == qu) + exit(1); + + for (i = 0; i < 6; i++) + { + tmp.id = i; + snprintf(tmp.name, NAMESIZE, "stu%d", i); + tmp.math = rand() % 100; + tmp.chinese = rand() % 100; + + if (0 != queue_en(qu, &tmp)) + break; + } + + while (1) + { + ret = queue_de(qu, &tmp); + if (-1 == ret) + break; + + print_s(&tmp); + } + + queue_destroy(qu); + + exit(0); +} \ No newline at end of file diff --git a/Chapter11/ds/line/squeue/list/queue.c b/Chapter11/ds/line/squeue/list/queue.c new file mode 100644 index 0000000..4447d23 --- /dev/null +++ b/Chapter11/ds/line/squeue/list/queue.c @@ -0,0 +1,26 @@ +#include "queue.h" + +QUEUE *queue_create(int size) +{ + return llist_create(size); +} + +int queue_en(QUEUE *ptr, const void *data) +{ + llist_insert(ptr, data, LLIST_BACKWARD); +} + +static always_match(const void *p1, const void *p2) +{ + return 0; +} + +int queue_de(QUEUE *ptr, void *data) +{ + return llist_fetch(ptr, (void *)0, always_match, data); +} + +void queue_destroy(QUEUE *ptr) +{ + llist_destroy(ptr); +} \ No newline at end of file diff --git a/Chapter11/ds/line/squeue/list/queue.h b/Chapter11/ds/line/squeue/list/queue.h new file mode 100644 index 0000000..75a20c7 --- /dev/null +++ b/Chapter11/ds/line/squeue/list/queue.h @@ -0,0 +1,16 @@ +#ifndef QUEUE_H__ +#define QUEUE_H__ + +#include "llist.h" + +typedef LLIST QUEUE; + +QUEUE *queue_create(int); + +int queue_en(QUEUE *, const void *); + +int queue_de(QUEUE *, void *); + +void queue_destroy(QUEUE *); + +#endif \ No newline at end of file