- Joined
- Jun 20, 2011
- Messages
- 249
JASS:
library MergeSort /* v3.0.1
*/uses/*
*/ LinkedListModule /* thehelper.net/forums/showthread.php/168775-LinkedListModule
A tool for sorting linked lists inside structs.
***********************************************************************
*
* textmacro MERGE_SORT takes METHOD_NAME, COMPARE_BOOLEAN
* - Run at the end of the struct.
*
***********************************************************************
*
* DEMONSTRATION
*
* struct UnitsByLife extends array
* implement LinkedListModule
* unit target
* //! runtextmacro MERGE_SORT ("sort","GetWidgetLife(v1.target)>GetWidgetLife(v2.target)")
* endstruct
*
* Assuming that you're going to insert instances to the UnitsByLife's
* base then you can call UnitsByLife.sort(UnitsByLife.base) to cause
* instances of the linked list to be sorted depending on each unit's
* current life. Reffer to the instances as "v1" and "v2"
**********************************************************************/
//! textmacro MERGE_SORT takes METHOD_NAME, COMPARE_BOOLEAN
//*********************************************************************
// Ok this method is entitled to split and merge constatly until there
// is nothing left to split.
private static method $METHOD_NAME$Ex takes thistype v1, thistype end returns thistype
local thistype v2=v1
local thistype list=v1
local thistype result=v1.prev
//*********************************************************************
// If the last node (end.prev) of the list is equal to the first node
// (v1) then skip.
if v1==end.prev then
return v1
endif
//*********************************************************************
// Find the halfway through the list by iterating two pointers forward
// one twice as fast as the other.
loop
set v2=v2.next
set list=list.next
exitwhen list==end
set list=list.next
exitwhen list==end
endloop
//*********************************************************************
// Now it calls this function again but for each v2 (from v1 up
// to the previous node from the v2 and from the v2 up to the end)
set v1=$METHOD_NAME$Ex(v1,v2)
set v2=$METHOD_NAME$Ex(v2,end)
//*********************************************************************
// Merges the list using 2 pointers: v1 and v2.
loop
if $COMPARE_BOOLEAN$ then
//*********************************************************************
// If the pointers pass the compare method it means that v2 needs to
// be placed behind v1.
set list=v2.next
//*********************************************************************
// So we remove v2 from the list...
call v2.removeNode()
//*********************************************************************
// ...and place it behind v1.
call v1.insertNode(v2)
//*********************************************************************
// After that we need v2 to point towards the node that was previously
// pointing to v2.next before, that's why i stored it inside "list" to
// now retreive it.
set v2=list
exitwhen v2==end
else
//*********************************************************************
// If the value doesn't pass the compare method it means there's no
// need for moving (the list is fine) and moves along
set v1=v1.next
exitwhen v1==v2
endif
endloop
return result.next
endmethod
//*********************************************************************
// head.next is the first value of the list and 0 the end.
static method $METHOD_NAME$ takes thistype head returns nothing
call $METHOD_NAME$Ex(head.next,head)
endmethod
//! endtextmacro
endlibrary
Attachments
Last edited: