Files
Linux-C-Notes/Chapter11/数据结构.md
2024-04-18 02:10:36 +08:00

223 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数据结构
## 架构梳理
- 线性1:1)
- 线性表
- 顺序存储 --> arr
- 链式存储 --> 指针 (有头,无头)
有头是指有一个不存数据的头,始终作为这个链表的起点。
会更加简单,无头的话,更改首部节点会麻烦。
头节点不仅可以作为起点,还可以作为存储信息的仓库,因为头节点只有*next是必须的。
- 单链表
- 循环
- 不循环
- 双向链表
`lib`四个版本,第一个最基础完善,第二个改成了变长结构体,第三个在第二个的基础上封装了函数指针,第四个在第二个的基础上隐藏了数据结构,只暴露接口。
- 循环
- 不循环
学到这里可以去读一下内核有关**list**的实现,主要都是宏和内联函数。
-
- 队列
练习:
1. 表达式计算
2. 球钟算法
三个栈1h5min1min。27个球过了多久队列里又是1到27的顺序。
- 树状1:N
**递归**。**递归**转**非递归**。
-N:M
## 静态库与动态库
- 静态库:
- 私家车,可以不在标准的位置下。
- 编译时引入,代码膨胀但是不影响运行时间。
- 动态库(共享库):
- 只能在指定的路径。
- 运行时引入,占用运行时间。
### 静态库
`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"`变为`<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`!