Binary Search Tree Module (worth my time?) +rep for thorough insight

GFreak45

I didnt slap you, i high 5'd your face.
Reaction score
130
NOTE: this library was not made to quickly add loads of data to a struct all at once and sort it instantly, this was made to be able to find the closest value to a specified value in under 20 conditions/variable adjustments and no function calls, and it is also not complete, but should i put more time into this and can it be a high quality resource in the future?

JASS:
library BST /* v0.01
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*                                                                                     *
*    Binary Search Tree Module v0.01                                                  *
*    by G_Freak45                                                                     *
*                                                                                     *
*    Requires:                                                                        *
*                                                                                     *
*    Some vJass knowledge, but no other libraries                                     *
*      'NOTE': Having some knowledge on linked lists and binary search trees isnt     *
*      needed but will help when using this system                                    *
*                                                                                     *
*    About the system:                                                                *
*                                                                                     *
*    Creates a dynamic binary search tree that sorts a linked list accordingly and    *
*    allows for incredibly quick searches for values in the sorted linked list.       *
*      'NOTE': This was not made to quickly add/remove isntances but rather find      *
*      the instance with the closest value to the value provided                      *
*                                                                                     *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*                                                                                     *
*    Methods, Modules, and Variables. Oh my!!!                                        *
*                                                                                     *
*    implement BST                                                                    *
*     -This module creates a binary search tree using a real value to sort the        *
*      available instances                                                            *
*                                                                                     *
*    implement BSTint (Coming Soon)                                                   *
*     -This module creates a binary search tree using integers to sort the struct     *
*                                                                                     *
*    private method BST_getValue takes nothing returns real                           *
*     -You must have this method in your struct 'ABOVE' the module                    *
*     -Struct isntances are sorted using this method to determine their values        *
*                                                                                     *
*    private static method find takes real r, thistype start returns thistype         *
*     -This method finds a value based on the available "real r" starting at the      *
*      specified starting instance, if the tree branched from this instance does      *
*      not contain the value requested within its min and max values it will          *
*      return its parent                                                              *
*        'NOTE': Always returns the "next" instance, or rounds up every time if it    *
*        is not equal to another instances value                                      *
*                                                                                     *
*    private boolean isTwin and private thistype nextTwin/prevTwin                    *
*     -isTwin can be used to determine if the instance has a twin (equal value)       *
*      instance, and nextTwin/prevTwin can be used to itterate through the list of    *
*      twins for a given twin instance                                                *
*                                                                                     *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*                                                                                     *
*    Additional Notes:                                                                *
*                                                                                     *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    module BST
        thistype parent
        thistype next
        thistype prev
        thistype left
        thistype right
        thistype sibling
        boolean isTwin
        thistype nextTwin
        thistype prevTwin
        thistype domTwin
        integer depth
        thistype nextDepth
        thistype prevDepth
        
        static thistype array recycleList
        static thistype listSize
        static thistype allocInterface
        static trigger allocTrig
        static thistype zeroChild
        
        private method find takes thistype start returns thistype
            local thistype loop = start
            local thistype ret
            if start = start.parent.left and start.parent.prev.value < this.value then
                return start.parent
            elseif start = start.parent.right and start.parent.next.value > this.value then
                return start.parent.next
            endif
            loop
                if this.value > loop.value then
                    set loop = loop.right
                    if loop.isNull == false then
                        set ret = loop
                    endif
                elseif this.value < loop.value then
                    set loop = loop.left
                    if loop.isNull == false then
                        set ret = loop
                    endif
                elseif this.value == loop.value then
                    return loop
                endif
                exitwhen (0 = loop.left and 0 = loop.right) or (this.value > loop.value and 0 == loop.right) or (this.value < loop.value and 0 == loop.left)
            endloop
            if this.value > ret.value then
                set ret = ret.prev
            endif
            return ret
        endmethod
        
        private static method allocCond takes nothing returns boolean
            local thistype this = allocInterface
            local thistype find
            call TriggerSleepAction(0.0001)
            set this.value = this.BST_getValue()
            set find = this.find(zeroChild)
            set this.depth = find.depth + 1
            set this.next = find
            set this.prev = find.prev
            set this.prev.next = this
            set find.prev = this
            if 0 != find.left and find.left.value == this.value then
                if not find.left.isNull then
                    set this.isTwin = true
                    set this.nextTwin = find.left
                    set this.prevTwin = find.left.prevTwin
                    set find.left.prevTwin = this
                    set this.prevTwin.nextTwin = this
                else
                    set this.isTwin = false
                    set this.left = find.left.left
                    set this.right = find.left.right
                    set this.left.parent = this
                    set this.right.parent = this
                    set this.next = find.left.next
                    set this.prev = find.left.prev
                    set this.next.prev = this
                    set this.prev.next = this
                endif
            elseif 0 != find.left and find.left.value != this.value then
                set this.prev.right = this
                set this.parent = this.prev
            else
                set find.left = this
                set this.parent = find
            endif
            return false
        endmethod
        
        private static method allocate takes real r returns thistype
            local thistype this = recycleList[0]
            if 0 == this then
                debug if listSize = 8190 then
                debug     call BJDebugMsg("BST ERROR: Your struct containing " + thistype.allocate.name + " has exceeded 8190 instances."
                debug     return 0
                debug endif
                set allocInterface = listSize
                call TriggerEvaluate(allocTrig)
                set listSize = listSize + 1
                return listSize
            endif
            set allocInterface = listSize
            call TriggerEvaluate(allocTrig)
            set recycleList[0] = recycleList[this]
            return this
        endmethod
        
        private method deallocate takes nothing returns nothing
            if this.isTwin = false then
                if 0 == this.left and 0 == this.right then
                    if this.parent.value > this.value then
                        set this.parent.left = 0
                    else
                        set this.parent.right = 0
                    endif
                    set this.parent = 0
                elseif 0 == this.left then
                    if this.parent.value > this.value then
                        set this.parent.left = this.right
                    else
                        set this.parent.right = this.right
                    endif
                    set this.right.parent = this.parent
                    set this.parent = 0
                    set this.right = 0
                elseif 0 == this.right then
                    if this.parent.value > this.value then
                        set this.parent.left = this.left
                    else
                        set this.parent.right = this.left
                    endif
                    set this.left.parent = this.parent
                    set this.parent = 0
                    set this.left = 0
                elseif SquareRoot(Pow(this.next.value - this.value, 2)) < SquareRoot(Pow(this.prev.value - this.value, 2)) then
                    set this.next.parent.left = 0
                    set this.next.parent = this.parent
                    set this.next.right = this.right
                    set this.next.left = this.left
                    set this.right.parent = this.next
                    set this.left.parent = this.next
                    if this.value > this.parent.value then
                        set this.parent.right = this.next
                    else
                        set this.parent.left = this.next
                    endif
                else
                    set this.prev.parent.left = 0
                    set this.prev.parent = this.parent
                    set this.prev.right = this.right
                    set this.prev.left = this.left
                    set this.right.parent = this.prev
                    set this.left.parent = this.prev
                    if this.value > this.parent.value then
                        set this.parent.right = this.prev
                    else
                        set this.parent.left = this.prev
                    endif
                endif
                set this.next.prev = this.prev
                set this.prev.next = this.next
            else
                if this.domTwin = this then
                    set this.nextTwin.parent = this.parent
                    set this.nextTwin.right = this.right
                    set this.nextTwin.left = this.left
                    set this.left.parent = this.nextTwin
                    set this.right.parent = this.nextTwin
                    set this.nextTwin.next = this.next
                    set this.nextTwin.prev = this.prev
                    set this.next.prev = this.nextTwin
                    set this.prev.next = this.nextTwin
                    if this.value > this.parent.value then
                        set this.parent.right = this.nextTwin
                    else
                        set this.parent.left = this.nextTwin
                    endif
                    set i = this.nextTwin.nextTwin
                    set this.nextTwin.prevTwin = this.prevTwin
                    set this.prevTwin.nextTwin = this.nextTwin
                    loop
                        exitwhen i == i.domTwin
                        set i.domTwin = this.nextTwin
                        set i = i.nextTwin
                    endloop
                else
                    set this.nextTwin.prevTwin = this.prevTwin
                    set this.prevTwin.nextTwin = this.nextTwin
                endif
            endif
        endmethod
    endmodule
endlibrary
 

Nestharus

o-o
Reaction score
84
#1, what kind of BST is this? If it's an AVL, I already wrote one.


http://www.thehelper.net/forums/showthread.php/167213-AVL-Tree


And that was gy'd since it didn't have a description, which it does have right now >.>, so no reason for it to be in the gy atm.


Now, if you want to code a red black tree, go for it. To my knowledge, nobody has done one yet, and there is a reason: they are a pain to code, lolz. There is also B-Tree, B+Tree, etc ^)^.
 

Dirac

22710180
Reaction score
147
Obviously Nes didn't read the code because he didn't notice the extremely amusing [ljass]call TriggerSleepAction(0.0001)[/ljass]
It's also quite obvious that you havent even tested it yet because the methods are private within the module what means you can't access them at the struct you implemented it in
 

GFreak45

I didnt slap you, i high 5'd your face.
Reaction score
130
dirac, that was so the values in the struct could be set after allocation, and that trigger is run during allocation
and you obviously havent changed your ways of not actually reading anything but the code provided
if you look about the jass tags there is something saying i just started it, that was a quick write up, so stop flaming, walk away, you fail
i actually respect nes' opinion because he actually takes the whole post into account and provides reasons for why or why not something isnt good or is
EDIT:
and i didnt ask for a test, asked if it was worth my time, dont post here, your input will be disregarded

&@Nest
i see that now, seems quite nice, however mine is a little different, the way im hoping to structure this is capable of shifting the tree in a way where neither side is imbalanced, ie:
when 1 child is added to one side it will check each parent to see if there are any imbalances, fixing them by taking the closest available value (ie: farthest right child of the left child of that parent) and swap position in the tree, then change the parent to be the right child (in this example) and the original left child of the parent to be the left one, both with a parent node based on the one that was just shifted, allowing for a very balanced tree and minimizing the procedures between searches, i didnt completely go over your code, but do you already do this?

as well as adding a linked list sorting every instance so that this.prev is the same as going to the left child and then all the way down the list of rights, making it way easier to find the closest value

EDIT2:
again @ nest
Mine also keeps track of twin values which yours apears not to, ie: 2 units have the same value that the BST_getValue method is based off, but they are 2 different units, etc

EDIT3:
again @ nest
I guess to answer your question What i am working on is a Balanced Binary Search Tree (the depth of each node does not differ by more than 1 and the ordering is made for searches), i havent seen any major differences between them and AVL trees, but i pretty much just glanced at AVLs
 

Dirac

22710180
Reaction score
147
I'm sorry, it's just that you have a reputation for posting codes that don't compile, so I took the most obvious fact about your code (methods being private) as proof that this wasn't an exception and I hope that I'm wrong.
Binary search seems rather useless in warcraft because you have hashtables, which allow O(1) search. As a sorting algorithm it's not very effective either.
However if you find a useful angle for this I advise you to follow the same API I used with MergeSort (a textmacro that takes the needed fields for arguments to be run inside structs, instead of a module) to increase flexibility and speed.
I'm not an expert in binary trees but I did once succesfully coded a binary heap for a (failed) timer system that used only one timer (I think that every coder that's worht a damn has tried to code that in addition to a knockback/slide system) and to my knowledge binary trees are best when:
-Are not temporal (instantly destroyed or only used for sorting)
-Retrieving only the first value, one at a time (rebuilding the tree does take a lot of overhead)
-You're Nestharus (otherwise no)
Why is allocating an instance causing a trigger to fire?
I still don't get what's that wait for
 

GFreak45

I didnt slap you, i high 5'd your face.
Reaction score
130
so they can have the allocated instance number, set values in an instant function and then the tree will be accurately adjusted, otherwise:
Get instance -> place in tree -> give allocated instance -> they change instance values -> instantly have to adjust in tree right after placing
when it should be
Get instance -> give allocated isntance -> they set values -> THEN place in tree

AND, i was testing whether or not i needed the wait at all if i used a trigger, this was mid-debugging when i had to stop for the day so i figured id post on here and ask if i should continue, i may have to even use [ljass]ExecuteFunc[/ljass] which would be terrible since its even slower than a trigger eval cuz it makes a new thread >.<

if you read what i said the system was for it was NOT to be used as:
  • A primary sorting algorithm
  • A rapidly changing struct

this is for only finding the instance containing the closest value as quickly as possible
and being balanced (same depth across the leaves) results in a max of 13 variable adjustments and condition checks (in an 8192 instance struct) to find the closest value

this could be used in a number of things and most specifically a timer merge system (to find the instance to place a timer in based on the current time)

as far as posting codes that dont compile...
I chose not to compile this for multiple reasons:
  1. its not done... so even if it could compile it would not work, period.
  2. because of 1, that would be a waste of time
  3. I was not asking what was wrong with the code, but more if the idea was a waste of time and i should look into something else

I understand modules cant have privates, but i have been writing structs for so long that i just naturally make everything private, i had to go back and delete that from the struct variables because i forgot with them as well, but i happened to look over the methods



@Nest
What is the use of a red black tree over a binary tree? as far as i can see each level just has it's own indicators as to red/black but i havent seen any use to have a differentiating depth qualifier except to make it retarded to adjust the tree (having to re-color up to 2^Distance from Leaves *almost* every time you adjust it, that sounds horridly inneficient ~.~
 

Nestharus

o-o
Reaction score
84
and being balanced (same depth across the leaves) results in a max of 13 variable adjustments and condition checks (in an 8192 instance struct) to find the closest value

Impossible >.>. Rebalancing takes max O(log n) as if you have to trace your path back up. Same with searching. It sounds like you are just doing an AVL Tree. Mine also has the linked list in it + hashtable for O(1) search of specific values (.has method). Furthermore, mine also includes the searchClose ; ).

What is the use of a red black tree over a binary tree? as far as i can see each level just has it's own indicators as to red/black but i havent seen any use to have a differentiating depth qualifier except to make it retarded to adjust the tree (having to re-color up to 2^Distance from Leaves *almost* every time you adjust it, that sounds horridly inneficient ~.~

red black does faster balancing than an AVL, but slower searches. If you are adding/removing from a tree lot more than doing searches, red black is a better option than AVL.


And wtf at 2^distance?? That's not true at all -.-.
 

GFreak45

I didnt slap you, i high 5'd your face.
Reaction score
130
guess the R/B tree still escapes me, ill have to look into it more >.<

and balancing isnt that difficult, you just need to know how to adjust the tree correctly, you to add 1 to one side just take the next or prev in the linked list (farthest left of a right child or farthest right of a left child basically) and swap it with the one you are adjusting, adding 1 to the tree that is over sized by 2 (thus rebalancing), as long as you know where to balance which would be recorded while doing a search

im doing the same library in C++ because i cant seem to find a good tree library there either, if only if only we could use pointers >.< that would make wc3 SO much more efficient

and at 2^Distance... how else do you change all the children of a whole branch under a changed node without it exponentially increasing the ammount of calls/variable changes you would need to make
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1
  • The Helper The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top