program linked_list
implicit none
type node
integer :: data
type(node), pointer :: next => null()
end type node
type(node), pointer :: head => null(), current => null(), prev => null()
integer :: choice, num
do
write(*,*) '1. Insert node'
write(*,*) '2. Delete node'
write(*,*) '3. Exit'
read(*,*) choice
select case (choice)
case (1)
write(*,*) 'Enter data to insert:'
read(*,*) num
call insert_node(head, num)
case (2)
write(*,*) 'Enter data to delete:'
read(*,*) num
call delete_node(head, num)
case (3)
call free_memory(head)
exit
case default
write(*,*) 'Invalid choice, please try again.'
end select
end do
contains
subroutine insert_node(head, num)
type(node), pointer, intent(inout) :: head
integer, intent(in) :: num
type(node), pointer :: new_node
allocate(new_node)
new_node%data = num
new_node%next => null()
if (head == null()) then
head => new_node
else
current => head
do while (current%next /= null())
current => current%next
end do
current%next => new_node
end if
end subroutine insert_node
subroutine delete_node(head, num)
type(node), pointer, intent(inout) :: head
integer, intent(in) :: num
logical :: found
found =.false.
if (head == null()) then
write(*,*) 'List is empty.'
return
end if
if (head%data == num) then
current => head
head => head%next
deallocate(current)
found =.true.
else
prev => head
current => head%next
do while (current /= null())
if (current%data == num) then
prev%next => current%next
deallocate(current)
found =.true.
exit
end if
prev => current
current => current%next
end do
end if
if (.not. found) then
write(*,*) 'Data not found in the list.'
end if
end subroutine delete_node
subroutine free_memory(head)
type(node), pointer, intent(inout) :: head
type(node), pointer :: temp
current => head
do while (current /= null())
temp => current
current => current%next
deallocate(temp)
end do
head => null()
end subroutine free_memory
end program linked_list
指针有效性处理
- 初始化指针:程序开始时,链表头指针
head
初始化为null()
,确保指针在使用前处于已知的无效状态,避免野指针。
- 空指针检查:在插入、删除和遍历链表的操作中,每次使用指针前都进行空指针检查。例如,在
insert_node
中,插入新节点前检查head
是否为空;在delete_node
中,操作前检查head
是否为空。
- 指针更新:在删除节点时,正确更新前一个节点的
next
指针,使其指向被删除节点的下一个节点,避免指针悬空。例如,prev%next => current%next
。
内存连续性处理
- 动态内存分配:使用
allocate
语句为新节点分配内存,Fortran的allocate
操作会在堆内存中寻找合适的连续内存块来满足分配请求。
- 不依赖连续内存:链表结构的特性决定了其节点在内存中不需要连续存储。每个节点通过指针连接,因此只要有足够的空闲内存,就能分配新节点,不依赖于内存的连续性。
潜在内存碎片化处理
- 及时释放内存:在删除节点时,使用
deallocate
语句及时释放不再使用的内存,避免内存泄漏。这有助于减少潜在的内存碎片化,因为操作系统可以将释放的内存块重新用于其他分配请求。
- 紧凑链表:由于链表节点在内存中不要求连续,理论上碎片化对链表结构本身的影响较小。但为了提高整体内存利用率,及时释放内存可以让操作系统更好地管理内存,减少碎片化的可能性。