Traverse from the beginning of a doubly-linked list to the end, and from the end to the beginning.



See also

 Array
 Associative array: Creation, Iteration
 Collections
 Compound data type
 Doubly-linked list: Definition, Element definition, Element insertion, List Traversal, Element Removal
 Linked list
 Queue: Definition, Usage
 Set
 Singly-linked list: Element definition, Element insertion, List Traversal, Element Removal
 Stack


 
struct block,nxt as ulong,prev as ulong,nm as char[20],age as long'Our structure of the blocks in our list.
 
global hHeap
global hFirst
global hLast
global blockCount
global blockSize
blockSize=len(block.struct)
 
 
    call Init
    if hHeap=0 then
        print "Error occured! Could not create heap, exiting..."
        end
    end if
 
    FirstUser=New("David",20)
    notImportant=New("Jessica",35)
    notImportant=New("Joey",38)
    MiddleUser=New("Jack",56)
    notImportant=New("Amy",17)
    notImportant=New("Bob",28)
    LastUser=New("Kenny",56)
 
 
    print "-Traversing the list forwards"
 
    hCurrent=hFirst
    while hCurrent<>0
        print tab(2);dechex$(hCurrent);"   ";Block.name$(hCurrent);"   ";Block.age(hCurrent)
        hCurrent=Block.next(hCurrent)
    wend
 
    print
    print "-Deleting first, middle, and last person."
 
    call Delete FirstUser'1
    call Delete MiddleUser'2
    call Delete LastUser'3
 
    print
    print "-Traversing the list backwards"
    hCurrent=hLast
    while hCurrent<>0
        print tab(2);dechex$(hCurrent);"   ";Block.name$(hCurrent);"   ";Block.age(hCurrent)
        hCurrent=Block.prev(hCurrent)
    wend
 
call Uninit
 
end
 
 
function Block.next(hBlock)
    calldll #kernel32,"RtlMoveMemory",block as struct,hBlock as ulong,blockSize as long,ret as void
    Block.next=block.nxt.struct
end function
 
function Block.prev(hBlock)
    calldll #kernel32,"RtlMoveMemory",block as struct,hBlock as ulong,blockSize as long,ret as void
    Block.prev=block.prev.struct
end function
 
function Block.age(hBlock)
    calldll #kernel32,"RtlMoveMemory",block as struct,hBlock as ulong,blockSize as long,ret as void
    Block.age=block.age.struct
end function
 
function Block.name$(hBlock)
    calldll #kernel32,"RtlMoveMemory",block as struct,hBlock as ulong,blockSize as long,ret as void
    Block.name$=block.nm.struct
end function
 
sub Block.age hBlock,age
    calldll #kernel32,"RtlMoveMemory",block as struct,hBlock as ulong,blockSize as long,ret as void
    block.age.struct=age
    calldll #kernel32,"RtlMoveMemory",hBlock as ulong,block as struct,blockSize as long,ret as void
end sub
 
sub Block.name hBlock,name$
    calldll #kernel32,"RtlMoveMemory",block as struct,hBlock as ulong,blockSize as long,ret as void
    block.nm.struct=name$
    calldll #kernel32,"RtlMoveMemory",hBlock as ulong,block as struct,blockSize as long,ret as void
end sub
 
sub Block.next hBlock,nxt
    calldll #kernel32,"RtlMoveMemory",block as struct,hBlock as ulong,blockSize as long,ret as void
    block.nxt.struct=nxt
    calldll #kernel32,"RtlMoveMemory",hBlock as ulong,block as struct,blockSize as long,ret as void
end sub
 
sub Block.prev hBlock,prev
    calldll #kernel32,"RtlMoveMemory",block as struct,hBlock as ulong,blockSize as long,ret as void
    block.prev.struct=prev
    calldll #kernel32,"RtlMoveMemory",hBlock as ulong,block as struct,blockSize as long,ret as void
end sub
 
function New(name$,age)
    calldll #kernel32,"HeapAlloc",hHeap as ulong,_HEAP_ZERO_MEMORY as ulong,blockSize as long,New as ulong
    if New<>0 then
        blockCount=blockCount+1
        if hFirst=0 then
            hFirst=New
            hLast=New
        else
            call Block.next hLast,New
            call Block.prev New,hLast
            hLast=New
        end if
        call Block.name New,name$
        call Block.age New,age
    end if
end function
 
sub Delete hBlock
    if hBlock<>0 then
        blockCount=blockCount-1
        if blockCount=0 then
            hFirst=0
            hLast=0
        else
            if hBlock=hFirst then
                hFirst=Block.next(hBlock)
                call Block.prev hFirst,0
            else
                if hBlock=hLast then
                    hLast=Block.prev(hBlock)
                    call Block.next hLast,0
                else
                    call Block.next Block.prev(hBlock),Block.next(hBlock)
                    call Block.prev Block.next(hBlock),Block.prev(hBlock)
                end if
            end if
        end if
        calldll #kernel32,"HeapFree",hHeap as ulong,0 as long,hBlock as ulong,ret as void
    end if
end sub
 
 
sub Init
    calldll #kernel32,"HeapCreate",0 as long,10000 as long,0 as long,hHeap as ulong
end sub
 
sub Uninit
    calldll #kernel32,"HeapDestroy",hHeap as ulong,ret as void
end sub
 