 ,
 ,this post is a spin-off from this conversation, which has moved thematically in a different direction.
I would like to ask here again if anyone has tips if and how to optimize this code to sort a structured list.
As you can see in the illustration, each list entry has an entry number (A) and some entries have a reference entry (B) that is referenced.
The sorting should now work in such a way that a referenced entry always comes before the entry that references it in the list.
(the red arrows are showing the reference path!)

This is my approach to achieve this.
The sorting in my use case is about max. 100 entries, nevertheless I would be interested if this can be optimized further.
Code: Select all
Structure MyStruct
	Entry.i
	RefEntry.i	
EndStructure
NewList StructList.MyStruct()
AddElement(StructList()) : StructList()\Entry = 100
AddElement(StructList()) : StructList()\Entry = 200 : StructList()\RefEntry =300
AddElement(StructList()) : StructList()\Entry = 300 : StructList()\RefEntry =600
AddElement(StructList()) : StructList()\Entry = 400
AddElement(StructList()) : StructList()\Entry = 500 : StructList()\RefEntry =600
AddElement(StructList()) : StructList()\Entry = 600 : StructList()\RefEntry =800
AddElement(StructList()) : StructList()\Entry = 700
AddElement(StructList()) : StructList()\Entry = 800 : StructList()\RefEntry =700
; SortStructuredList(StructList(), #PB_Sort_Ascending, OffsetOf(MyStruct\RefEntry), TypeOf(MyStruct\RefEntry))
ForEach StructList()
	Debug "Entry: " + Str(StructList()\Entry) + " - Ref to: " + Str(StructList()\RefEntry)
Next
Debug "----------------------------"
SearchStart = 0
SearchEnd = ListSize(StructList()) - 1
ProcessCounter = 0
For i = SearchStart To SearchEnd - 1
	Debug "Processing entry no. " + Str(i)
	SelectElement(StructList(), i)
	ProcessCounter + 1
	If StructList()\RefEntry > 0
		*Entry = @StructList()
		RefEntry.i = StructList()\RefEntry
		Debug "     Searching for RefEntry: " +Str(RefEntry)
		For j = i + 1 To SearchEnd
			SelectElement(StructList(), j)
			ProcessCounter + 1
			Debug "          Search @pos " + Str(j) + "... entry " + Str(StructList()\Entry)
			If StructList()\Entry = RefEntry
				If StructList()\RefEntry > 0
					Debug "          Found! Move entry from position " + Str(j) + " before entry at position " + Str(i) + " and restart the search at the last processed entry."
					i - 1
				Else	
					Debug "          Found! Move entry from position " + Str(j) + " before entry at position " + Str(i) + " and restart the search at the following entry after the last processed entry."
				EndIf
				MoveElement(StructList(), #PB_List_Before, *Entry)
				Break
			EndIf
			If j = SearchEnd And SearchStart < SearchEnd
				Debug "No need to move, continue the search with the next entry."
			EndIf
		Next
	EndIf
Next
Debug ""
Debug "--------------" + Str(ProcessCounter) + " entries processed ----------------------------"
Debug ""
ForEach StructList()
	Debug "Entry: " + Str(StructList()\Entry) + " - Ref to: " + Str(StructList()\RefEntry)
Next
I didn't measure efficiency in runtime, but rather in the number of items to process in the two loops. And I think that the list is still processed here far too often.
I also haven't tried yet if a previous sorting using SortStructuredList() reduces the subsequent sorting effort.
Glad to hear any hints and comments.
Kurzer
EDIT: PS: I updated the code and was able to reduce the number of accesses to the list from 42 accesses to 41 accesses with the current version. LOL
Debug output wrote: [19:04:21] [Debug] Entry: 100 - Ref to: 0
[19:04:21] [Debug] Entry: 200 - Ref to: 300
[19:04:21] [Debug] Entry: 300 - Ref to: 600
[19:04:21] [Debug] Entry: 400 - Ref to: 0
[19:04:21] [Debug] Entry: 500 - Ref to: 600
[19:04:21] [Debug] Entry: 600 - Ref to: 800
[19:04:21] [Debug] Entry: 700 - Ref to: 0
[19:04:21] [Debug] Entry: 800 - Ref to: 700
[19:04:21] [Debug] ----------------------------
[19:04:21] [Debug] Processing entry no. 0
[19:04:21] [Debug] Processing entry no. 1
[19:04:21] [Debug] Searching for RefEntry: 300
[19:04:21] [Debug] Search @pos 2... entry 300
[19:04:21] [Debug] Found! Move entry from position 2 before entry at position 1 and restart the search at the last processed entry.
[19:04:21] [Debug] Processing entry no. 1
[19:04:21] [Debug] Searching for RefEntry: 600
[19:04:21] [Debug] Search @pos 2... entry 200
[19:04:21] [Debug] Search @pos 3... entry 400
[19:04:21] [Debug] Search @pos 4... entry 500
[19:04:21] [Debug] Search @pos 5... entry 600
[19:04:21] [Debug] Found! Move entry from position 5 before entry at position 1 and restart the search at the last processed entry.
[19:04:21] [Debug] Processing entry no. 1
[19:04:21] [Debug] Searching for RefEntry: 800
[19:04:21] [Debug] Search @pos 2... entry 300
[19:04:21] [Debug] Search @pos 3... entry 200
[19:04:21] [Debug] Search @pos 4... entry 400
[19:04:21] [Debug] Search @pos 5... entry 500
[19:04:21] [Debug] Search @pos 6... entry 700
[19:04:21] [Debug] Search @pos 7... entry 800
[19:04:21] [Debug] Found! Move entry from position 7 before entry at position 1 and restart the search at the last processed entry.
[19:04:21] [Debug] Processing entry no. 1
[19:04:21] [Debug] Searching for RefEntry: 700
[19:04:21] [Debug] Search @pos 2... entry 600
[19:04:21] [Debug] Search @pos 3... entry 300
[19:04:21] [Debug] Search @pos 4... entry 200
[19:04:21] [Debug] Search @pos 5... entry 400
[19:04:21] [Debug] Search @pos 6... entry 500
[19:04:21] [Debug] Search @pos 7... entry 700
[19:04:21] [Debug] Found! Move entry from position 7 before entry at position 1 and restart the search at the following entry after the last processed entry.
[19:04:21] [Debug] Processing entry no. 2
[19:04:21] [Debug] Searching for RefEntry: 700
[19:04:21] [Debug] Search @pos 3... entry 600
[19:04:21] [Debug] Search @pos 4... entry 300
[19:04:21] [Debug] Search @pos 5... entry 200
[19:04:21] [Debug] Search @pos 6... entry 400
[19:04:21] [Debug] Search @pos 7... entry 500
[19:04:21] [Debug] No need to move, continue the search with the next entry.
[19:04:21] [Debug] Processing entry no. 3
[19:04:21] [Debug] Searching for RefEntry: 800
[19:04:21] [Debug] Search @pos 4... entry 300
[19:04:21] [Debug] Search @pos 5... entry 200
[19:04:21] [Debug] Search @pos 6... entry 400
[19:04:21] [Debug] Search @pos 7... entry 500
[19:04:21] [Debug] No need to move, continue the search with the next entry.
[19:04:21] [Debug] Processing entry no. 4
[19:04:21] [Debug] Searching for RefEntry: 600
[19:04:21] [Debug] Search @pos 5... entry 200
[19:04:21] [Debug] Search @pos 6... entry 400
[19:04:21] [Debug] Search @pos 7... entry 500
[19:04:21] [Debug] No need to move, continue the search with the next entry.
[19:04:21] [Debug] Processing entry no. 5
[19:04:21] [Debug] Searching for RefEntry: 300
[19:04:21] [Debug] Search @pos 6... entry 400
[19:04:21] [Debug] Search @pos 7... entry 500
[19:04:21] [Debug] No need to move, continue the search with the next entry.
[19:04:21] [Debug] Processing entry no. 6
[19:04:21] [Debug]
[19:04:21] [Debug] --------------41 entries processed ----------------------------
[19:04:21] [Debug]
[19:04:21] [Debug] Entry: 100 - Ref to: 0
[19:04:21] [Debug] Entry: 700 - Ref to: 0
[19:04:21] [Debug] Entry: 800 - Ref to: 700
[19:04:21] [Debug] Entry: 600 - Ref to: 800
[19:04:21] [Debug] Entry: 300 - Ref to: 600
[19:04:21] [Debug] Entry: 200 - Ref to: 300
[19:04:21] [Debug] Entry: 400 - Ref to: 0
[19:04:21] [Debug] Entry: 500 - Ref to: 600




