swap any node Doubly linked list, python

Update: 12-23-17
Found a bug, adding a fix. The first if, depends on the node1 or node2 having a prev,  and they may or may not.  I tried adding this function set_sides() to my swap_left(self) also and it kept rejecting it... will figure that out later.   Christmas is here, and trying to quicksort this doubly linked list.... is driving me mad.... Does anyone actually sort a doubly linked list inside a doubly linked list with this swap method??

Happy joyful whatever holidays you may celebrate,  and Merry Christmas too!


I'll be adding this to my old Doubly Linked List post.

It uses my swap_left method for if nodes are next to each other...
I will go and see if I can combine these after I get the quicksort figured out.  I'm sure it's possible, but I'm debating if they should be combined. Another one of those, I don't know enough about how these lists are used and manipulated to know if it's a good idea to put that much control over the list into one method....  But it kinda is.... because I use the left_swap in the swap_any...

Anyhoo.....   Less gremlins lurking on this one.  Once I figured out the order in which the links had to be reset and established.....

If you do it in the wrong order,  the nodes will runaway with nothing to chain them to your list. Especially since python likes to clean things up for you.  If there's no reference to the thing, python will garbage collect it.... POOF... gone... Makes this sorting stuff kinda scary ... If this was important data and I did this wrong...  Gone!

I tested this with my print methods, and count methods...   the where_begin() uses self.begin and next to go through list ,  and the graphical uses  self.end  previous links to go through the list.  I used count() to make sure also that counting from the front of the list, I still had all my items.  My graphical shows the counts, so that part was covered for going prev... to get counts.

OK, enough of that.   Here is the swap_any() for doubly linked list.


 def swap_any(self, node1, node2):

#[or NONE spam -- n1-->][<---spam---node1--eggs--->][<--n1--eggs or NONE]
#[or NONE bags -- n2-->][<---bags---node2---nots-->]<---n2--nots or NONE]
        ### make sure they are not next to each other ###
        def set_sides(node1, node2):
            if node1.prev != None:
                node1prev = node1.prev
            else:
                node1prev = None
            if node1.next != None:
                node1next = node1.next
            else:
                node1next = None
            if node2.prev != None:
                node2prev = node2.prev
            else:
                node2prev = None
            if node2.next != None:
                node2next = node2.next
            else:
                node2next = None
            return node1prev, node1next, node2prev, node2next

        node1prev, node1next, node2prev, node2next = set_sides(node1,node2)


        if node1prev == node2 or node2prev == node1 or node1next == node2 or node2next == node1:
            ## might have to fix swap_left..... I think it doesn't care which order they are

            self.swap_left(node1,node2)


        elif node1.prev != None and node1.next != None and node2.next != None and node2.prev != None:

            print(" swap any 1")
            ### not sure why this order is important...
            ## ohhhhh............
            ## you change the link by accessing it through the original node given...
            ## if you change that node before the address get's assigned it will assign 
            ## a wrong address......  try to add something later to show it.
            node1.prev.next = node2 #spam         
            node2.prev.next = node1 #bags
            node1.next.prev = node2 #eggs
            node2.next.prev = node1 #nots

           # this swaps the links without having to set any temps.
            node1.prev, node2.prev = node2.prev, node1.prev
            node2.next, node1.next = node1.next, node2.next
         
         
        elif node1.prev == None and node2.next != None:
            ## node1 is a begin node:
            print(" Swap begin node,  node 1 .....")
            #node1.prev.next = node2 #spam 
            node2.prev.next = node1 #bags
            node2.next.prev = node1 #nots
            node1.next.prev = node2 #eggs       
         
         
       
            node1.prev, node2.prev = node2.prev, node1.prev
            node2.next, node1.next = node1.next, node2.next
            self.begin = node2
            #print(f"{node1}{node2}")

        elif node2.prev == None and node1.next != None:
            ## node2 is a begin node:
            print(" Swap begin node, node 2...")
            node1.prev.next = node2 #spam         
            #node2.prev.next = node1 #bags
            node1.next.prev = node2 #eggs
            node2.next.prev = node1 #nots

       
            node1.prev, node2.prev = node2.prev, node1.prev
            node2.next, node1.next = node1.next, node2.next
            self.begin = node1

        elif node1.next == None and node2.prev != None:
            ## node1 is an end node:
            print(" node1 is end node,  swap")
            node1.prev.next = node2 #spam         
            node2.prev.next = node1 #bags
            #node1.next.prev = node2 #eggs
            node2.next.prev = node1 #nots

       
            node1.prev, node2.prev = node2.prev, node1.prev
            node2.next, node1.next = node1.next, node2.next

            self.end = node2

        elif node2.next == None and node1.prev != None:
            #node 2 is an end node:
            print(" end node swap,  node 2 .....")
            node1.prev.next = node2 #spam         
            node2.prev.next = node1 #bags
            node1.next.prev = node2 #eggs
            #node2.next.prev = node1 #nots

       
            node1.prev, node2.prev = node2.prev, node1.prev
            node2.next, node1.next = node1.next, node2.next

            self.end = node1

        elif node1.prev == None and node2.next == None:
            # node1 is a begin node, node2 is an end node:
            print(" swap node1 begin,  node2 end ")
            #node1.prev.next = node2 #spam         
            node2.prev.next = node1 #bags
            node1.next.prev = node2 #eggs
            #node2.next.prev = node1 #nots


            node1.prev, node2.prev = node2.prev, node1.prev
            node2.next, node1.next = node1.next, node2.next

            self.end = node1
            self.begin = node2
            print(f"{node1} : {node2}")

        elif node2.prev == None and node1.next == None:
            # node 2 is begin,  node 1  is end:
            print(" swap node2 begin, node1 end ...")
            node1.prev.next = node2
            node2.next.prev = node1

            node1.prev, node2.prev = node2.prev, node1.prev
            node2.next, node1.next = node1.next, node2.next

            self.end = node2
            self.begin = node1

         

        else:
            print(" not complete -----------")
     

Comments

Popular posts from this blog

Statistics, Python, Making a Stem Plot

Pandas Python and a little probability

JavaScript Ascii animation with while loops and console.log