Doubly-linked list/Definition: Difference between revisions

Content added Content deleted
m (Exchanged start/end)
Line 650: Line 650:
? list
? list
# value: <0, 1, 5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20></lang>
# value: <0, 1, 5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20></lang>


=={{header|fortran}}==
<lang fortran>
module dlist
implicit none
type node
type(node), pointer :: next => null()
type(node), pointer :: prev => null()
integer :: data
end type node

type dll
type(node), pointer :: head => null()
type(node), pointer :: tail => null()
integer :: num_nodes = 0
end type dll

public :: node, dll, append, prepend, insert, dump, reverse_dump, tidy
private :: init

contains
! Create a new doubly-linked list
type(dll) function new_dll()
new_dll = dll()
return
end function new_dll

! Append an element to the end of the list
subroutine append(dl2, value)
type(dll), intent(inout) :: dl2
integer, intent(in) :: value

type(node) :: element
type(node), pointer :: np

! If the list is empty
if (dl2%num_nodes == 0) then
call init(dl2, value)
return
end if

! Add new element to the end
dl2%num_nodes = dl2%num_nodes + 1
np => dl2%tail
allocate(dl2%tail)
dl2%tail%data = value
dl2%tail%prev => np
dl2%tail%prev%next => dl2%tail
end subroutine append

! Prepend an element to the beginning of the list
subroutine prepend(dl2, value)
type(dll), intent(inout) :: dl2
integer, intent(in) :: value

type(node) :: element
type(node), pointer :: np

if (dl2%num_nodes == 0) then
call init(dl2, value)
return
end if

dl2%num_nodes = dl2%num_nodes + 1
np => dl2%head
allocate(dl2%head)
dl2%head%data = value
dl2%head%next => np
dl2%head%next%prev => dl2%head
end subroutine prepend

! Insert immediately before the given index
subroutine insert(dl2, index, value)
type(dll), intent(inout) :: dl2
integer, intent(in) :: index
integer, intent(in) :: value

type(node), pointer :: element
type(node), pointer :: np1, np2
integer :: i

if (dl2%num_nodes == 0) then
call init(dl2, value)
return
end if

! If index is beyond the end then append
if (index > dl2%num_nodes) then
call append(dl2, value)
return
end if

! If index is less than 1 then prepend
if (index <= 1) then
call prepend(dl2, value)
return
end if

! Find the node at position 'index' counting from 1
np1 => dl2%head
do i=1, index-2
np1 => np1%next
end do
np2 => np1%next

! Create the new node
allocate(element)
element%data = value

! Connect it up
element%prev => np1
element%next => np2
np1%next => element
np2%prev => element
dl2%num_nodes = dl2%num_nodes + 1
end subroutine insert

subroutine dump(dl2)
type(dll), intent(in) :: dl2
type(node), pointer :: current
integer :: i

write(*,fmt='(a,i0,a)',advance='no') 'Doubly-linked list has ',dl2%num_nodes,' element - fwd = '
current => dl2%head
i = 1
write(*,fmt='(i0,a)',advance='no') current%data,', '
do
current => current%next
if (.not. associated(current)) then
exit
end if
i = i + 1
if (i == dl2%num_nodes) then
write(*,'(i0)') current%data
else
write(*,fmt='(i0,a)',advance='no') current%data,', '
end if
end do
end subroutine dump

subroutine reverse_dump(dl2)
type(dll), intent(in) :: dl2
type(node), pointer :: current
integer :: i

write(*,fmt='(a,i0,a)',advance='no') 'Doubly-linked list has ',dl2%num_nodes,' element - bwd = '
current => dl2%tail
write(*,fmt='(i0,a)',advance='no') current%data,', '
i = 1
do
current => current%prev
if (.not. associated(current)) then
exit
end if
i = i + 1
if (i == dl2%num_nodes) then
write(*,'(i0)') current%data
else
write(*,fmt='(i0,a)',advance='no') current%data,', '
end if
end do
end subroutine reverse_dump

! Deallocate all allocated memory
subroutine tidy(dl2)
type(dll), intent(in) :: dl2
type(node), pointer :: current, last

current => dl2%head
do
last => current
current => current%next
if (associated(last)) then
deallocate(last)
end if
if (associated(current, dl2%tail)) then
deallocate(current)
exit
end if
end do
end subroutine tidy

subroutine init(dl2, value)
type(dll), intent(inout) :: dl2
integer, intent(in) :: value
allocate(dl2%head)
dl2%tail => dl2%head
dl2%tail%data = value
dl2%num_nodes = 1
return
end subroutine init

end module dlist

program dl
use dlist
implicit none

type(dll) :: mydll

mydll = new_dll()
call append(mydll, 5)
call append(mydll, 7)
call prepend(mydll, 3)
call prepend(mydll, 1)
call insert(mydll, 3, 4)
call dump(mydll)

call reverse_dump(mydll)

call tidy(mydll)
end program dl
</lang>

Output:
<pre>
Doubly-linked list has 5 element - fwd = 1, 3, 4, 5, 7
Doubly-linked list has 5 element - bwd = 7, 5, 4, 3, 1
</pre>


=={{header|F Sharp|F#}}==
=={{header|F Sharp|F#}}==