Snippet The QSort Algorithm

SerraAvenger

Cuz I can
Reaction score
234
The QuickSort Algorithm

requires:
- JassPack NewGen
- Jass Knowledge


This code sorts the ToSort array and the ParallelSort one at the same time.
It works quite fast, for the smaller subarrays it uses insert sort to keep the stack lower and for the bigger sorting it uses QSort with some sort of "median of two". Simply copy this in your map header, and then copy the array you want to sort in the ToSort array, run QSort on the fields you want to sort ( like from 2 to 700, use QSort( 2 , 700 ) ) and then copy the data back.

JASS:
//*********************************************************************
// The Quicksort Algorithm                                            *
//   - Median of two ; Insertsort for arrays of 4 and less-           *
// Expected efficiency  : O( n * log n )                              *
// Worst case efficiency: O( n² )                                     *
//**********************************************************************************************************************
//* !!! All array members that will be sorted need to have a value! All Parallelsort fields need to have a value too!  *
//* !!! The Tosort Variable needs to be of Type Integer!                                                               *
//* !!! To use it, write //! runtextmacro QSORT( the array to be sorted, the array to be parallely sorted, and the     *
//*     type of the array that is sorted parallely. Example:                                                           *
//*     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    *
//      globals                                                                                                        
//          integer array HeroLevel                                                                                    
//          unit    array Heroes                                                                                       
//          integer       NumHeroes                                                                                    
//      endglobals                                                                                                     
//                                                                                                                     
//      //! runtextmacro QSORT( HeroLevel , Heroes, unit )                                                             
//                                                                                                                     
//      function DisplayMaxHeroLevel takes nothing returns nothing                                                         
//          call QSortHeroLevel( 0 , NumHeroes )
//          call DisplayTextToPlayer( GetLocalPlayer() , 0 , 0 , "|cffffcc00The highest-level Hero is " + GetUnitName( Heroes[ NumHeroes ] ) )                                                                                *
//      endfunction
//     
//*    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - -    *
//*    So to make the array sortable, run the textmacro. Then to actually sort it, use                                 *
//*           
//          call QSort[the array to be sorted]( lower sorting bound , upper sorting bound )
//*
//*    Not difficult at all, is it?                                                                                    *
//*    Only bad thing: You allways need a filled parallelsort for it, which needs to be different from the array to be *
//*    sorted. Most probably you would've needed it anyway, but not allways.                                           *
//**********************************************************************************************************************
//* Coded by Cpt.DaveyJones/SerraAvenger, invented by C. A. R. Hoare

library QuickSort

//! textmacro QSORT takes TOSORT , PARALLELSORT , PARALLELTYPE

    
    function InsertSort$TOSORT$ takes integer lowerbound, integer upperbound returns nothing
        local integer outerLoop = lowerbound + 1
        local integer innerLoop
        local integer key                                                    
        local $PARALLELTYPE$ lock      
        loop
            exitwhen outerLoop > upperbound
            set innerLoop = outerLoop

            set key  = $TOSORT$      [ outerLoop ]
            set lock = $PARALLELSORT$[ outerLoop ]
            loop
                exitwhen innerLoop <= lowerbound
                exitwhen $TOSORT$ [ innerLoop - 1 ] < key
                set $TOSORT$      [ innerLoop ] = $TOSORT$      [ innerLoop - 1 ]
                set $PARALLELSORT$[ innerLoop ] = $PARALLELSORT$[ innerLoop - 1 ]
                set innerLoop     = innerLoop - 1
            endloop
            set $TOSORT$      [ innerLoop ] = key
            set $PARALLELSORT$[ innerLoop ] = lock
            
            set outerLoop = outerLoop + 1
        endloop
        //if not ("$PARALLELTYPE$" == "integer" or "$PARALLELTYPE$" == "real"  ) then
        //    set lock = null
        //endif 
    endfunction
    

    function QSort$TOSORT$ takes integer lowerbound, integer upperbound returns nothing
        local integer pivot          = ( $TOSORT$[ lowerbound ] + $TOSORT$[ upperbound ] + $TOSORT$[ GetRandomInt( lowerbound, upperbound ) ] ) / 3
        local integer leftIndicator  = lowerbound
        local integer rightIndicator = upperbound
        local integer tempValue
        local $PARALLELTYPE$ tempParallelValue 
        if upperbound - lowerbound > 8 then

            loop

                loop
                    exitwhen $TOSORT$[ rightIndicator ] < pivot
                    exitwhen rightIndicator == leftIndicator 
                    set rightIndicator = rightIndicator - 1
                endloop
                loop
                    exitwhen $TOSORT$[ leftIndicator ] >= pivot
                    exitwhen leftIndicator == rightIndicator
                    set leftIndicator = leftIndicator + 1
                endloop
                exitwhen leftIndicator > rightIndicator
                
                set tempValue                  = $TOSORT$[ rightIndicator ]
                set $TOSORT$[ rightIndicator ] = $TOSORT$[ leftIndicator  ]
                set $TOSORT$[ leftIndicator  ] = tempValue


                set tempParallelValue                = $PARALLELSORT$[ rightIndicator ]
                set $PARALLELSORT$[ rightIndicator ] = $PARALLELSORT$[ leftIndicator  ]
                set $PARALLELSORT$[ leftIndicator  ] = tempParallelValue
            endloop
            call QSort$TOSORT$( lowerbound         , leftIndicator )                                                                        
            call QSort$TOSORT$( rightIndicator + 1 , upperbound    )

        else
            call InsertSort$TOSORT$( lowerbound, upperbound )
        endif
        
    endfunction
    
//! endtextmacro                             
endlibrary

If anyone requests a demo map I'll add one, but I don't think that sorting would need demonstration : /

Hf with your faster sorting
Davey

EDIT: Uploaded Demo map. Simply open it with Grimoire running and enter -test XXXX , with XXXX being the integer on your choice. It will then fill the first XXXX fields of the ToSort array with random integers between 1 and XXXX, and then apply quicksort. After the sorting has finished, all the numbers will be shown in sorted order. After 740 it will most probably hit the op limiter.

Demo map and attached text file currently out of date! Please do not use.
 

Attachments

  • QSortTest.w3x
    20 KB · Views: 229
  • QSort.txt
    4.7 KB · Views: 260

Cohadar

master of fugue
Reaction score
209
wow nice one :)

I see someone has been paying attention at school ;)

Try making heapsort after this, I believe it will work faster than qsort in jass.
It is easier to code anyways.

heh, you just made my day with this, +rep.
 

SerraAvenger

Cuz I can
Reaction score
234
Hm I thought of making Binary search first, and then I still can do other sorting algorithms.

@Flare: It sorts an array from the lowest to the highest number. Helps when you want to use bsearch lateron, or if you want to sort players after their kills, ( bit overkill there, you might aswell just use the integrated Insert Sort ), to sort units for their hitpoints, to sort ... Basically any integer / real, just need to change the variable.
 

SerraAvenger

Cuz I can
Reaction score
234
so for example, i have a leaderboard measuring kills. with this, i can arrange the kills of each player, and then list them from highest to lowest on the leaderboard? if so, fair enough, seems like a useful enough reason :D

Yes, although leaderboards can sort themselves. It would be better used on multiboards. Simply use the ParallelSort for the PlayerIds, and QSort then.
Greetings Davey
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,495
> like from 2 to 12414

12000+ ?


How many values, on average, can this sort before hitting the operation limit?
How many values do you need at least for this to be faster than bubble sort?

And, to sort a multiboard, I definitely recommend a leaderboard.
Sorting is instant, and you get the players for free.
 

SerraAvenger

Cuz I can
Reaction score
234
> like from 2 to 12414

12000+ ?


How many values, on average, can this sort before hitting the operation limit?
How many values do you need at least for this to be faster than bubble sort?

And, to sort a multiboard, I definitely recommend a leaderboard.
Sorting is instant, and you get the players for free.

Sorting works in JASS for arround 740 integers before hitting the op limit, 700 is recommended. Sorting works instantly for 740 integers. Especially for long multiboards, I recommend this ; P

That's why I use Insertion sort on partitions of 5 or less, right ; ) Thus Bubblesort is never faster than this.
 

SerraAvenger

Cuz I can
Reaction score
234
Bump

wow nice one :)

I see someone has been paying attention at school ;)

Try making heapsort after this, I believe it will work faster than qsort in jass.
It is easier to code anyways.

heh, you just made my day with this, +rep.

Got a better Idea. Let's use bogosort!


j/k
 

SerraAvenger

Cuz I can
Reaction score
234
BUMP
1. why did this get into Graveyard?^^
2. I tested with an optimized Bubblesort, and it raised expetions at 100 items in the best case. So allready this version was 7 times better, and it ahd a small bug: I forgot a tiny > ^^
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top