From 46005cd4fea57b796a2c2a96689bfb4d139c33b0 Mon Sep 17 00:00:00 2001 From: lzy Date: Thu, 18 Apr 2024 02:10:36 +0800 Subject: [PATCH] =?UTF-8?q?=E7=90=83=E9=92=9F=E7=AE=97=E6=B3=95=E4=B8=8E?= =?UTF-8?q?=E9=9D=99=E6=80=81=E5=BA=93=E5=8A=A8=E6=80=81=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chapter11/ds/line/ball_clock/Makefile | 31 +++++ Chapter11/ds/line/ball_clock/main.c | 113 ++++++++++++++++ Chapter11/ds/line/ball_clock/queue.c | 72 ++++++++++ Chapter11/ds/line/ball_clock/queue.h | 29 ++++ Chapter11/ds/line/ball_clock/sqstack.c | 72 ++++++++++ Chapter11/ds/line/ball_clock/sqstack.h | 30 +++++ Chapter11/ds/line/stack/list/main.c | 2 +- Chapter11/数据结构.md | 180 +++++++++++++++++++++++++ 8 files changed, 528 insertions(+), 1 deletion(-) create mode 100644 Chapter11/ds/line/ball_clock/Makefile create mode 100644 Chapter11/ds/line/ball_clock/main.c create mode 100644 Chapter11/ds/line/ball_clock/queue.c create mode 100644 Chapter11/ds/line/ball_clock/queue.h create mode 100644 Chapter11/ds/line/ball_clock/sqstack.c create mode 100644 Chapter11/ds/line/ball_clock/sqstack.h diff --git a/Chapter11/ds/line/ball_clock/Makefile b/Chapter11/ds/line/ball_clock/Makefile new file mode 100644 index 0000000..a7681ed --- /dev/null +++ b/Chapter11/ds/line/ball_clock/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/ball_clock/main.c b/Chapter11/ds/line/ball_clock/main.c new file mode 100644 index 0000000..bb5e165 --- /dev/null +++ b/Chapter11/ds/line/ball_clock/main.c @@ -0,0 +1,113 @@ +/** + * @file main.c + * @brief 球钟算法 + * + * @author lzy (lllzzzyyy@buaa.edu.cn) + * @url https://lzyyyyyy.fun + * + * @date 2024-04-18 + * + */ +#include +#include + +#include "queue.h" +#include "sqstack.h" + +#define NR_BALL 27 + +int check(queue *qu) +{ + int i = (qu->head + 1) % MAXSIZE; + + do + { + if (qu->data[i] > qu->data[(i + 1) / MAXSIZE]) + return 0; + i = (i + 1) % MAXSIZE; + } while (i != qu->tail); + + return 1; +} + +int main() +{ + int i; + queue *qu; + int t, value; + int time; + sqstack *st_min, *st_fivemin, *st_hour; + + qu = qu_create(); + if (NULL == qu) + exit(1); + + st_min = st_create(); + if (NULL == st_min) + exit(1); + + st_fivemin = st_create(); + if (NULL == st_fivemin) + exit(1); + + st_hour = st_create(); + if (NULL == st_hour) + exit(1); + + + for (i = 1; i <= NR_BALL; i++) + qu_enqueue(qu, &i); + + qu_travel(qu); + + while (1) + { + qu_dequeue(qu, &t); + time++; + + if (st_min->top != 3) + { + st_push(st_min, &t); + } + else + { + while (!st_isempty(st_min)) + { + st_pop(st_min, &value); + qu_enqueue(qu, &value); + } + if (st_fivemin->top != 10) + st_push(st_fivemin, &t); + else + { + while (!st_isempty(st_fivemin)) + { + st_pop(st_fivemin, &value); + qu_enqueue(qu, &value); + } + if (st_hour->top != 10) + st_push(st_hour, &t); + else + { + while (!st_isempty(st_hour)) + { + st_pop(st_hour, &value); + qu_enqueue(qu, &value); + } + qu_enqueue(qu, &t); + if (check(qu)) + break; + } + } + } + } + + printf("time = %d\n", time); + + qu_destroy(qu); + st_destroy(st_min); + st_destroy(st_fivemin); + st_destroy(st_hour); + + exit(0); +} \ No newline at end of file diff --git a/Chapter11/ds/line/ball_clock/queue.c b/Chapter11/ds/line/ball_clock/queue.c new file mode 100644 index 0000000..d1b3631 --- /dev/null +++ b/Chapter11/ds/line/ball_clock/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/ball_clock/queue.h b/Chapter11/ds/line/ball_clock/queue.h new file mode 100644 index 0000000..411c8b2 --- /dev/null +++ b/Chapter11/ds/line/ball_clock/queue.h @@ -0,0 +1,29 @@ +#ifndef QUEUE_H__ +#define QUEUE_H__ + +#define MAXSIZE 32 + +typedef int datatype; + +typedef struct +{ + 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/ball_clock/sqstack.c b/Chapter11/ds/line/ball_clock/sqstack.c new file mode 100644 index 0000000..5f2f8f4 --- /dev/null +++ b/Chapter11/ds/line/ball_clock/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, type *data) +{ + if (SIZE - 1 == st->top) + return -1; + + st->data[++st->top] = *data; + + return 0; +} + +/* 取出栈顶元素 */ +int st_pop(sqstack *st, type *data) +{ + if (st_isempty(st)) + return -1; + + *data = st->data[st->top--]; + + return 0; +} + + +/* 查看栈顶元素 */ +int st_top(sqstack *st, type *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/ball_clock/sqstack.h b/Chapter11/ds/line/ball_clock/sqstack.h new file mode 100644 index 0000000..9ed979f --- /dev/null +++ b/Chapter11/ds/line/ball_clock/sqstack.h @@ -0,0 +1,30 @@ +#ifndef SQSTACK_H__ +#define SQSTACK_H__ + +#define SIZE 32 + +typedef int type; + +typedef struct node_st +{ + type data[SIZE]; + int top; +} sqstack; + +sqstack *st_create(void); + +int st_isempty(sqstack *); + +int st_push(sqstack *, type *); + +/* 取出栈顶元素 */ +int st_pop(sqstack *, type *); + +/* 查看栈顶元素 */ +int st_top(sqstack *, type *); + +void st_travel(sqstack *); + +void st_destroy(sqstack *); + +#endif \ No newline at end of file diff --git a/Chapter11/ds/line/stack/list/main.c b/Chapter11/ds/line/stack/list/main.c index 72312b6..ef2e64f 100644 --- a/Chapter11/ds/line/stack/list/main.c +++ b/Chapter11/ds/line/stack/list/main.c @@ -1,7 +1,7 @@ #include #include -#include "stack.h" +#include #define NAMESIZE 32 diff --git a/Chapter11/数据结构.md b/Chapter11/数据结构.md index 32819fc..a9481f6 100644 --- a/Chapter11/数据结构.md +++ b/Chapter11/数据结构.md @@ -33,6 +33,11 @@ - 队列 +练习: +1. 表达式计算 +2. 球钟算法 + 三个栈,1h,5min,1min。27个球,过了多久队列里又是1到27的顺序。 + - 树状(1:N) **递归**。**递归**转**非递归**。 @@ -41,3 +46,178 @@ +## 静态库与动态库 + +- 静态库: + - 私家车,可以不在标准的位置下。 + - 编译时引入,代码膨胀但是不影响运行时间。 +- 动态库(共享库): + - 只能在指定的路径。 + - 运行时引入,占用运行时间。 + + + +### 静态库 + +`libxx.a` +xx 指代库名 + +`ar -cr libxx.a yyy.o` + + +发布到 +`/usr/local/include` +`/usr/local/lib` + +`gcc -L/usr/local/lib -o main main.o -lxx` +如果路径都是这个默认的,可省略。 +`-l`参数必须在最后,有依赖 + +`ldd -print shared libirary dependencies` +打印所用到的动态库的内容 + + +以链式双向链表的`lib2`为例。 + +```bash +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ldd ./main + linux-vdso.so.1 (0x00007ffffa3d0000) + libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa6c123a000) + /lib64/ld-linux-x86-64.so.2 (0x00007fa6c142b000) + *[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ gcc -c llist.c +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ls + llist.c  llist.o  Makefile + llist.h  main.c +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ar -cr libllist.a llist.o +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ls + libllist.a  llist.h  main.c + llist.c  llist.o  Makefile +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ sudo cp llist.h /usr/local/include +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ sudo cp libllist.a /usr/local/lib +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ gcc -o main main.c -lllist +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ls + libllist.a  llist.h  main  Makefile + llist.c  llist.o  main.c +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ./main +6 std6 90 59 +5 std5 62 27 +4 std4 49 21 +3 std3 86 92 +2 std2 93 35 +1 std1 77 15 +0 std0 83 86 + + +5 std5 62 27 +4 std4 49 21 +3 std3 86 92 +2 std2 93 35 +1 std1 77 15 +0 std0 83 86 +``` +这时`main.c`路径下都不需要`llist.c`和`llist.h`了,`#include`时也从`"llist.h"`变为``。 + + +### 动态库 + +`libxx.so` +xx为库名 + +`gcc -shared -fpic -o libxx.so yyy.c` + +发布到 +`/usr/local/include` +`/usr/local/lib` + +在`/etc/ld.so.conf`中添加路径 +`/sbin/ldconfig` 重读`/etc/ld.so.conf` + +`gcc -I/usr/local/include -L/usr/local/lib -o ... -lxx` +如果路径都是这个默认的,可省略。 + +非root用户发布,可以自己定义一个位置,例如`~/lib` +```bash +cp xx.co ~/lib +export LD_LIBRARY_PATH= ~/lib +``` + + +```bash +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ls + llist.c  llist.h  main  main.c  Makefile +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ gcc -shared -fpic -o libllist.so llist.c +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ls + libllist.so  llist.h  main.c + llist.c  main  Makefile +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ sudo mv libllist.so /usr/local/lib +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ sudo vi /etc/ld.so.conf +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ sudo /sbin/ldconfig +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ gcc -o main main.c -lllist +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ./main +6 std6 90 59 +5 std5 62 27 +4 std4 49 21 +3 std3 86 92 +2 std2 93 35 +1 std1 77 15 +0 std0 83 86 + + +5 std5 62 27 +4 std4 49 21 +3 std3 86 92 +2 std2 93 35 +1 std1 77 15 +0 std0 83 86 +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/list/linklist/double/lib2]$ ldd ./main + linux-vdso.so.1 (0x00007ffd963ee000) + libllist.so => /usr/local/lib/libllist.so (0x00007fda74025000) + libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fda73e44000) + /lib64/ld-linux-x86-64.so.2 (0x00007fda7403a000) +``` + +当动态库和静态库重名,会优先链接**静态库**。 + +以链式存储栈为例,`libstack`依赖`libllist`。 +```bash +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ ls + llist.c  main  Makefile  stack.o + llist.h  main.c  stack.c + llist.o  main.o  stack.h +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ gcc -shared -fpic -o libstack.so stack.c +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ ls + libstack.so  llist.o  main.o  stack.h + llist.c  main  Makefile  stack.o + llist.h  main.c  stack.c +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ sudo mv libstack.so /usr/local/lib +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ sudo cp stack.h /usr/local/include +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ code main.c +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ ls + llist.c  main  Makefile  stack.o + llist.h  main.c  stack.c + llist.o  main.o  stack.h +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ gcc -o main main.c -lstack +/usr/bin/ld: /usr/local/lib/libstack.so: undefined reference to `llist_create' +/usr/bin/ld: /usr/local/lib/libstack.so: undefined reference to `llist_fetch' +/usr/bin/ld: /usr/local/lib/libstack.so: undefined reference to `llist_destroy' +/usr/bin/ld: /usr/local/lib/libstack.so: undefined reference to `llist_insert' +collect2: error: ld returned 1 exit status +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ gcc -o main main.c -lstack -lllist +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ ./main +./main: error while loading shared libraries: libstack.so: cannot open shared object file: No such file or directory +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ sudo /sbin/ldconfig +/sbin/ldconfig: Can't link /usr/lib/wsl/lib/libnvoptix_loader.so.1 to libnvoptix.so.1 +/sbin/ldconfig: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link + +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ gcc -o main main.c -lstack -lllist +*[main][~/workspace/Linux-C-Notes/Chapter11/ds/line/stack/list]$ ./main +6 stu6 90 59 +5 stu5 62 27 +4 stu4 49 21 +3 stu3 86 92 +2 stu2 93 35 +1 stu1 77 15 +0 stu0 83 86 +``` + +添加动态库记得重载配置文件`sudo /sbin/ldconfig`! \ No newline at end of file