Ok, here are examples of both an unsorted list, combining inuse & free lists into a single array, and a sorted version too using a binary search.
These use my array plug-in to make them more efficient (much more for the sorted one).
First, the unsorted - add two items, remove one, then add another, plus/minus shows whether the item is in use (+), or in the free list (-):
type MyType_T
Key as integer
Data1 as integer
Data2 as float
endtype
global dim MyArray() as MyType_t
` Next plug-in release will allow this to work:
`set array index MyArray(), -1
` Until then...
array index to top MyArray()
previous array index MyArray()
PrintArray(0)
AddNewUnordered()
MyArray().Key = 123
AddNewUnordered()
MyArray().Key = 456
PrintArray(100)
RemoveUnordered(0)
PrintArray(200)
AddNewUnordered()
MyArray().Key = 789
PrintArray(300)
wait key
end
function AddNewUnordered()
next array index MyArray()
if array index valid( MyArray() ) = 0 then array insert at bottom MyArray()
endfunction
function RemoveUnordered(Index as integer)
swap array items MyArray(), Index, get array index( MyArray() )
previous array index MyArray()
endfunction
function PrintArray(x as integer)
local i as integer
local y as integer
y = 0
text x, y, "Size: " + str$( array count( MyArray() ) )
inc y, 15
text x, y, "Index: " + str$( get array index( MyArray() ) )
inc y, 30
for i = 0 to get array index( MyArray() )
text x, y, "+ " + str$(i) + " : " + str$( MyArray(i).Key )
inc y, 15
next
for i = get array index( MyArray() ) + 1 to array count( MyArray() )
text x, y, "- " + str$(i) + " : " + str$( MyArray(i).Key )
inc y, 15
next
endfunction
This provides an unsorted inuse and free list - It's fairly simple to understand. If you wish to grow the array in chunks, this will also work.
Next the sorted list - this requires a binary search for insertion and removal, and this time I'm using the ROTATE ARRAY command to insert items into the correct place in the list:
type MyType_T
Key as integer
Data1 as integer
Data2 as float
endtype
global dim MyArray() as MyType_t
` Next release will allow this to work:
`set array index MyArray(), -1
` Until then...
array index to top MyArray()
previous array index MyArray()
PrintArray(0)
AddNewOrdered(123)
AddNewOrdered(456)
PrintArray(100)
RemoveOrdered(123)
PrintArray(200)
AddNewOrdered(789)
PrintArray(300)
wait key
end
function AddNewOrdered(Key as integer)
local Index as integer
Index = SearchOrdered(Key, 1) ` find match or insert point
if Index > get array index( MyArray() )
` Append
next array index MyArray()
if array index valid( MyArray() ) = 0 then array insert at bottom MyArray()
MyArray().Key = Key
else
if MyArray(Index).Key <> Key
` Insert
next array index MyArray()
if array index valid( MyArray() ) = 0 then array insert at bottom MyArray()
MyArray().Key = Key
rotate array MyArray(), 1, Index, get array index( MyArray() )
endif
endif
endfunction Index
function RemoveOrdered(Key as integer)
local Index as integer
Index = SearchOrdered( Key, 0 ) ` find exact match only
if Index >= 0
rotate array MyArray(), -1, Index, get array index( MyArray() )
previous array index MyArray()
endif
endfunction
function SearchOrdered(Key as integer, Nearest as integer)
local High as integer
local Low as integer
local Middle as integer
Low = -1
High = get array index( MyArray() ) + 1
while High - Low > 1
Middle = (High + Low) / 2
if MyArray(Middle).Key < Key
Low = Middle
else
High = Middle
endif
endwhile
if Nearest = 0
if High > get array index( MyArray() ) then exitfunction -1
if MyArray(High).Key <> Key then exitfunction -1
endif
endfunction High
function PrintArray(x as integer)
local i as integer
local y as integer
y = 0
text x, y, "Size: " + str$( array count( MyArray() ) )
inc y, 15
text x, y, "Index: " + str$( get array index( MyArray() ) )
inc y, 30
for i = 0 to get array index( MyArray() )
text x, y, "+ " + str$(i) + " : " + str$( MyArray(i).Key )
inc y, 15
next
for i = get array index( MyArray() ) + 1 to array count( MyArray() )
text x, y, "- " + str$(i) + " : " + str$( MyArray(i).Key )
inc y, 15
next
endfunction
Of course, if you have a lot to load, it may be better to insert into your list using an unordered insert, then sort the array for the inuse range, and then maintain it using the ordered insert from that point on.
@BatVink, You'll probably need to modify this slightly to use a two-part key as I said in a previous post (Group & ID).