Skip to content

Commit 3e449df

Browse files
authored
Create ch08-04-list.md
1 parent cf69a50 commit 3e449df

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

src/ch08-04-list.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# 链表
2+
3+
此处我们只讨论最简单的单链表结构,其他更加复杂的数据结构读者可以自行编写
4+
5+
## node的定义
6+
将指针与结构体结合,就可以创建动态的数据结构
7+
``` fortran
8+
module node_mod
9+
implicit none
10+
type node_t
11+
integer::x
12+
type(node_t),pointer::next=>null()
13+
end type node_t
14+
end module node_mode
15+
```
16+
17+
## 链表
18+
可以一直为`next`指针分配内存,形成一个链,这样的数据结构称为链表
19+
20+
``` fortran
21+
program main
22+
use node_mod
23+
implicit none
24+
type(node_t),pointer::tail=>null()
25+
type(node_t),target ::list
26+
integer::i
27+
list%x=0
28+
tail=>list
29+
do i=1,10
30+
allocate(tail%next)!分配内存
31+
tail=>tail%next !指向末尾
32+
tail%x=i !赋值
33+
end do
34+
tail=>list
35+
do
36+
write(*,*)tail%x
37+
if(.not.associated(tail%next))exit !如果tail%next没分配,代表到了链表的末尾
38+
tail=>tail%next !指向下一个
39+
end do
40+
end program main
41+
```
42+
43+
## 使用`allocatable`定义递归结构
44+
需要注意的是,也也可以使用`allocatable`来创建这样的结构
45+
``` fortran
46+
type node_t
47+
integer::x
48+
type(node_t),allocatable::next
49+
end type node_t
50+
```
51+
但是两者略有不同,当有两个变量`type(node_t)::a,b`执行`a=b`的操作时,**对于`pointer`属性,`a%next``b%next`指向同一块内存,而对于`allocatable`属性`a%next``b%next`指向不同的内存**
52+
53+
- 注:`gfortran`在实现该功能的时候存在bug,所以均是指向同一块内存。`ifort,ifx,flang`没问题
54+
- 通过重载赋值运算符`=`,可以避免这个bug
55+
``` fortran
56+
module test
57+
implicit none
58+
type node_t
59+
integer::x
60+
type(node_t),pointer::next=>null()
61+
end type node_t
62+
type node_a
63+
integer::x
64+
type(node_a),allocatable::next
65+
end type node_a
66+
end module test
67+
68+
program main
69+
use test
70+
implicit none
71+
type(node_t)::t,t1
72+
type(node_a)::a,a1
73+
t%x=1
74+
allocate(t%next)
75+
t%next%x=2
76+
t1=t
77+
write(*,*)t1%next%x
78+
write(*,*)loc(t1%next),loc(t%next)!loc是编译器扩展语法,可以输出变量的地址,指针的地址相同
79+
80+
a%x=1
81+
allocate(a%next)
82+
a%next%x=2
83+
a1=a
84+
write(*,*)a1%next%x
85+
write(*,*)loc(a1%next),loc(a%next)!可分配的地址不同
86+
end program main
87+
```
88+
89+
# 习题
90+
- 尝试对链表实现插入操作
91+
- (提高)尝试使用`allocatable`实现一个单链表,并实现插入操作(提示:注意使用`move_alloc`)
92+
- (提高)使用自定义类型实现一个`list`类型,并绑定`append,insert,remove`操作,并实现析构函数
93+
94+

0 commit comments

Comments
 (0)