def __init__(self): '''(WackyQueue) -> NoneType This is the init method in <WackyQueue> for initializing variables ''' # create odd and even linked list both with a dummy WackyNode self._oddlist = WackyNode(None, 0) self._evenlist = WackyNode(None, 0)
def __init__(self): '''(WackyQueue) -> NoneType constructs an empty queue ''' # Representation invariant: self._head1 = WackyNode(None, None) self._head2 = WackyNode(None, None)
def __init__(self): ''' (WackyQueue) -> NoneType REQ: oddlist and evenlist must be link list ''' self._oddlist = WackyNode(None, None) # dummy node self._evenlist = WackyNode(None, None) # dummy node
def __init__(self): '''(WackyQueue) -> NoneType constructs an empty queue ''' # Representation invariant: # WackyQueue consists of two linked lists # _head1 is a dummy head of the linked list of odd nodes # _head2 is a dummy head of the linked list of even nodes # _head1.get_next() is the first node in the list of odd nodes # _head1.get_next() is the first node in the WackyQueue # _head2.get_next() is the first node in the list of even nodes # _head2.get_next() is the second node in the WackyQueue self._head1 = WackyNode(None, None) self._head2 = WackyNode(None, None)
def insert(self, obj, pri): '''(WackyQueue, obj, int) -> NoneType insert an object to queue, whose priority = pri and item = obj ''' # create a new node with obj and pri given new_node = WackyNode(obj, pri) # set 3 pointers that point to 2 head nodes and the 1st node prev = self._head1 curr = self._head2 next = self._head1.get_next() # find the right place for insertion by comparing the priority of # the current object and the objects that are already in the queue while (next is not None) and (next.get_priority() >= pri): # move to the next node now = next next = curr.get_next() prev = curr curr = now # when find the right place # insert the new node after the prev node prev.set_next(new_node) # if the curr node has a _next node if (curr.get_next() is not None): # set this node to be the _next of the new node new_node.set_next(curr.get_next()) # set next node to be the _next of the curr node curr.set_next(next)
def __init__(self): '''(WackyQueue) -> None This method instanciates a WackyQueue ''' # Representation Invariant # _size is how many objects the Queue contains # _head is the head of the one of the WackyQueues # _head2 is the second head of the WackyWueues # The hgher the number, the greater its priority # Which ever head holds 0 as its priority is the head of the odd # list # if self._head.get_priority is 0, it is the head of the odd list # if self._head2.get_priority is 0, it is the head of the odd list # END OF REPRESENTATION INVARIANT # Now cretaed the WackyHeads holding no information and # pointing to nothing # Make self._head's priotiry 0 by defualt to be the head of the odd # list, you will see why later. self._head = WackyNode(None, 0) self._head2 = WackyNode(None, 1)
def insert(self, obj, pri, node=None, curr=None, next=None): if not node: # for changepriority (in case you check for same node) node = WackyNode(obj, pri) if not curr: # for changepriority (avoid starting from head) curr, next = self._oddlist, self._evenlist while curr.get_next() and curr.get_next().get_priority() >= pri: next, curr = curr.get_next(), next node.set_next(next.get_next()) next.set_next(curr.get_next()) curr.set_next(node)
def __init__(self): ''' (WackyQueue) -> None Returns None and initializes all the instance variables needed for the class ''' # Representation Invariant: # > what are the instances used and what data structure is used for # them? # _even_list is a linked list # _odd_list is a linked list # > what are the things inside of this data structure? # items inside _even_list and _odd_list are stored as WackyNodes # > what is the arrangement of these items, if they follow a specific # pattern # _even_list stores all the objects that are inserted in even insertion # numbers (0, 2, 4...) # _odd_list stores all the objects that are inserted in odd insertion # numbers (1, 3, 5...) # initialize the lists with a nodes aka head self._odd_list = WackyNode(None, None) self._even_list = WackyNode(None, None)
def insert(self, item, pri): '''(WackyQueue, obj, int) -> NoneType Insert a WackyNode with <item> object and <pri> as its priority into WackyQueue ''' def insert_process(insert_node, before, after, gap, connect): '''(WackyNode, WackyNode, WackyNode, WackyNode, WackyNode) -> NoneType A helper function for the process when inserting a WackyNode in the WackyQueue, it organizes the WackyQueue in correct order after inserting ''' # connect the insert WackyNode in correct order before.set_next(insert_node) insert_node.set_next(after) gap.set_next(connect) # create a WackyNode to insert new_node = WackyNode(item, pri) # initialize variables for looping by heapler function curr, oprev, ocurr, eprev, ecurr = set_variables( self._oddlist, self._evenlist) # create a flag. When flag is True, current and odd current are # at the same position, vise versa flag = True # loop through two linked list to find the insert position while curr and curr.get_priority() >= pri: # check if current and odd current are at the same position if flag: # Do the looping process by helper function curr, oprev, ocurr = loop_process(curr, oprev, ocurr, curr.get_next(), ecurr) # else current and even current are at the same position else: # Do the looping process by helper function curr, eprev, ecurr = loop_process(curr, eprev, ecurr, curr.get_next(), ocurr) # switch the state of flag flag = not flag # if current and odd current are at the same position after the loop if flag: # insert the new WackyNode in correct order by helper function insert_process(new_node, oprev, ecurr, eprev, ocurr) # else current and even current are at same position after the loop else: # insert the new WackyNode in correct order by helper function insert_process(new_node, eprev, ocurr, oprev, ecurr)
def insert(self, obj, pri): '''(WackyQueue, object, int) -> NoneType Insert object obj with priority pri into the wacky queue ''' # create a new Wacky Node Newnode = WackyNode(obj, pri) # case 1: it is the first inserted Node in the list, the list is empty if (self._Oddhead is None): self._Oddhead = Newnode else: # use help funtion to find the position whose # priority is less than pri cur, pre, double_pre, Oddcur, Evencur, is_end, is_odd =\ self._find_pri_pos(pri) # use help function to insert the Newnode in the position self._insert_pos(Newnode, cur, pre, double_pre, Oddcur, Evencur, is_end, is_odd)
# Initialize the heads pointing to the 2 linked lists - odd and even self._odd_head = None self._even_head = None """ ANNOTATION 2: Method should be less than 73 lines """ def insert(self, item, priority): """ END ANNOTATION 2 """ ''' (WackyQueue, obj, int) -> NoneType """ ANNOTATION 1: How do the priorities work? """ Insert an item with a priority into the Wacky Queue. Duplicates are allowed - wacky queue may contain same copies of obj with same or different priorities. """ END ANNOTATION 1 """ ''' # Create a new node that will be inserted into the wacky queue new_node = WackyNode(item, priority) # If the WackyQueue is empty, add the new node to the first position of # WackyQueue (first position of odd linked list) if self._odd_head is None: self._odd_head = new_node # If the WackyQueue contains only one node and if the new node has a # priority greater than the first node, elif ((self._even_head is None) and (new_node.get_priority() > self._odd_head.get_priority())): # Switch the first node to the second node's position and insert # new node to first node's position self._even_head = self._odd_head self._odd_head = new_node # If the WackyQueue contains only one node and if the priority of new # node is lesser than that of first node,
def insert(self, obj, pri): '''(WackyQueue, object, int) -> None This method puts an object in the Wacky Queue depending on its priority ''' # Create the new node new_node = WackyNode(obj, pri) # First you want to find the spot where the new node will go. 'in-head' # means the operation is currently in self._head and is loking for # where to insert the item # We also want to start comparing items from the top of the list if self._head.get_priority() is 0: current_check = 'in-head' current_node = self._head.get_next() elif self._head2.get_priority() is 0: current_check = 'in-head2' current_node = self._head2.get_next() # Next you want to make sure that the current node is not None if current_node is not None: current_pri = current_node.get_priority() # You want to keep track of what node was visited last in each list last_head_node = self._head last_head2_node = self._head2 # Loop through BOTH lists, by alternating until you find the spot while (current_node is not None) and (pri <= current_pri): # create a condition that does alternate checking if current_check == 'in-head': # Keep track of both current and LAST Nodes last_head_node = current_node current_node = last_head2_node.get_next() # Next you want to make sure that the current node is not None if current_node is not None: current_pri = current_node.get_priority() # Now to alternate make the current check to point to head2 current_check = 'in-head2' elif current_check == 'in-head2': # Keep track of both current and LAST Nodes last_head2_node = current_node current_node = last_head_node.get_next() if current_node is not None: current_pri = current_node.get_priority() # Now to alternate make the current check to point to head2 current_check = 'in-head' # When the spot is found, depending on the obj of the head, that is # where you inserting it # Do not forget to push all the other items down the list # If the current_check is 'in-head', then you want to PUT the new node # in head if current_check == 'in-head': # Get the next node of the last node you visited in head2 # Make the new node point to that new_node.set_next(last_head2_node.get_next()) # Make the last node you visited in head2 point to the current node last_head2_node.set_next(current_node) # Make the last node you visited in head point to the new node last_head_node.set_next(new_node) # If the current_check is 'in-head2', then you want to PUT the new node # in head2 elif current_check == 'in-head2': # Then get the next node of the last node you visited in head # Point the new node to the next node of the last node you visited # in head new_node.set_next(last_head_node.get_next()) # Now point the last node you visited in head and point it to the # current node last_head_node.set_next(current_node) # Also, get the last node you visited before the current node, # then point that node to the new node. last_head2_node.set_next(new_node)
def insert(self, obj, pri): ''' (WackyQueue, obj, int) -> NoneType This function takes in an object with a priority and insert it into the proper position of the two link list REQ: the pri must be an integer ''' # set the new node new_node = WackyNode(obj, pri) # set the basic pointers for the odd list prev = None curr = self._oddlist.get_next() # set the basic pointer for the even list prev_even = None curr_even = self._evenlist.get_next() # loop through every obj to find a place to insert while curr and curr_even and curr.get_priority() >= pri and\ curr_even.get_priority() >= pri: # move forward the pointer on the odd list prev = curr curr = curr.get_next() # move forward the pointer on the even list prev_even = curr_even curr_even = curr_even.get_next() if not curr: if self._oddlist._next is None: self._oddlist.set_next(new_node) else: # if curr is none, then the new node is smaller than # both prev and prev_even prev.set_next(new_node) elif not curr_even: # if curr is not none but curr_even is none # there are two occations: if self._evenlist._next is None: if pri <= self._oddlist.get_next().get_priority(): self._evenlist.set_next(new_node) else: self._evenlist.set_next(self._oddlist.get_next()) self._oddlist.set_next(new_node) else: if pri <= curr.get_priority(): # if pri is less than odd curr value # then it is inserted into the even list at last prev_even.set_next(new_node) else: # if pri is bigger than curr value # of course less or equal to prev_even value # then the new node is inserted after the prev prev.set_next(new_node) prev_even.set_next(curr) elif pri > curr_even.get_priority() and pri <= curr.get_priority(): # if pri is between the value of curr and curr_even # then the new node is inserted after the prev_even # link the new node with the curr position in even list if prev_even is None: self._evenlist.set_next(new_node) else: prev_even.set_next(new_node) # link the new node with the next object in odd list new_node.set_next(curr.get_next()) # link the curr position in odd list # with the next object in even list curr.set_next(curr_even) elif pri > curr.get_priority(): # if pri's value is bigger than curr's value # of course less or equal to prev_even value # link prev in odd list with new node if prev is None: self._oddlist.set_next(new_node) else: prev.set_next(new_node) # link the new node with the curr obj in even list new_node.set_next(curr_even) # link the prev position in even list with curr position in odd if prev_even is None: self._evenlist.set_next(curr) else: prev_even.set_next(curr)
def changepriority(self, obj, pri): '''(WackyQueue, object, int) -> NoneType Change the priority of the first copy of object obj to pri. The wacky queue is unchanged if obj is not in it or already has priority pri. If the priority of obj is changed, then the insertion time of obj is taken to be the time of the changepriority operation. ''' # find the first Node whose item is the object in this list # find whether there exist the same priority in the list # find the position whose pri is less than pri cur, pre, double_pre, is_same, cur_pri, pre_pri, double_pre_pri,\ pri_Even, pri_Odd, pri_is_end, pri_is_odd\ = self._first_obj_same_priority(obj, pri) # change the priority when obj is in it and do not have same pri if (is_same is False and cur is not None): # if the pri is less than the first object's pri and # large than or euql to the next node's pri # just change the priority for the first node if (cur == pre_pri or cur == cur_pri): cur.set_priority(pri) # it is the first oddlist node and the second last node in the list elif (cur.get_next() is None and self._Oddhead == cur and pri_is_end is True): cur.set_priority(pri) self._Evenhead = cur self._Oddhead = cur_pri # the first node is the second last node in list # and will be in the last elif (cur.get_next() is None and pre.get_next() is not None and pri < cur_pri.get_priority()): cur.set_priority(pri) double_pre.set_next(cur_pri) pre.set_next(cur) # the first node will switch the position with the node before it elif (pre == cur_pri and double_pre is not None and double_pre_pri is not None): cur.set_priority(pri) temp = cur.get_next() cur.set_next(cur_pri.get_next()) double_pre_pri.set_next(cur) double_pre.set_next(cur_pri) cur_pri.set_next(temp) # the pri is less than first object and large than # the next node of next node of this object's pri elif (cur == double_pre_pri): cur.set_priority(pri) cur.set_next(pre_pri.get_next()) pre_pri.set_next(cur_pri) # case 1: the first object is the first node in the odd list if (pre is None and double_pre is None): self._Evenhead = cur self._Oddhead = pre_pri # case 2: the first object is the first node in even list elif (double_pre is None and pre is not None): pre.set_next(cur) self._Evenhead = pre_pri # case 3: the general case else: pre.set_next(cur) double_pre.set_next(pre_pri) else: # remove this object from the list # case 1: the first object is the first node in odd list if (double_pre is None and pre is None): # point the Oddhead to the Evenhead # point the Evenhead to second node in the odd list self._Oddhead = self._Evenhead self._Evenhead = cur.get_next() # case 2: the first object is the first node in even list elif (double_pre is None and pre is not None): # point Evenhead to the next node of pre # point the pre node to next node of cur self._Evenhead = pre.get_next() pre.set_next(cur.get_next()) # case 3: the general case else: # remove the Node with first obj in the list # set the next node of cur node to be # the next node of pre node # set the next node pf pre node to be the next # node of double pre node double_pre.set_next(pre.get_next()) pre.set_next(cur.get_next()) # insert the Node to the sepcific position # create a new Wacky Node Newnode = WackyNode(obj, pri) # case 1: the list is empty if (self._Oddhead is None): self._Oddhead = Newnode else: self._insert_pos(Newnode, cur_pri, pre_pri, double_pre_pri, pri_Odd, pri_Even, pri_is_end, pri_is_odd)
def insert(self, obj, pri): '''(WackyQueue, obj, int) -> NoneType Creates a new WackyNode and inserts it into the WackyQueue sorted descendingly. Items with the same priority are sorted according to which item was added first. ''' # Create node node = WackyNode(obj, pri) # Insert first item if self._odd is None: self._odd = node # Insert the second item if # it has less priority than first elif self._even is None and node.get_priority( ) <= self._odd.get_priority(): self._even = node # Switch the first and second if # second node has greater priority elif self._even is None and node.get_priority( ) > self._odd.get_priority(): self._even = self._odd self._odd = node # Insert the nth item, where n > 2 else: # Store the first and second nodes cur_node1 = self._odd cur_node2 = self._even # Keep track of the size of both lists sizeodd = 1 sizeeven = 1 # Take the nodes with the highest possible # priority from both lists while ( cur_node1.get_next() is not None and (cur_node1.get_next().get_priority() >= node.get_priority())): sizeodd += 1 cur_node1 = cur_node1.get_next() while ( cur_node2.get_next() is not None and (cur_node2.get_next().get_priority() >= node.get_priority())): sizeeven += 1 cur_node2 = cur_node2.get_next() # First Case: # The current nodes priorities taken from the # even and odd lists are greater than or equal # to the node priority if (cur_node1.get_priority() >= node.get_priority() and cur_node2.get_priority() >= node.get_priority()): # Find greater value between two current nodes # By default assume the odd list contains the higher node greatest = cur_node1 lowest = cur_node2 if cur_node1.get_priority() < cur_node2.get_priority(): greatest = cur_node2 lowest = cur_node1 elif cur_node1.get_priority() == cur_node2.get_priority(): # If odd list is longer, add node to the even list if sizeodd > sizeeven: greatest = cur_node2 lowest = cur_node1 temp = greatest.get_next() greatest.set_next(node) node.set_next(lowest.get_next()) lowest.set_next(temp) # Second Case: # The node priority is strictly inbetween the two # priorities or equal to the first odd node's priority elif (cur_node1.get_priority() >= node.get_priority() and cur_node2.get_priority() < node.get_priority()): # Insert in between temp = cur_node1.get_next() cur_node1.set_next(cur_node2) self._even = node node.set_next(temp) # Third Case: # The node priority is strictly greater than both elif (cur_node1.get_priority() < node.get_priority() and cur_node2.get_priority() < node.get_priority()): # Insert at the beginning temp = cur_node1 self._odd = node node.set_next(cur_node2) self._even = temp
def insert(self, item, priority): ''' (WackyQueue, obj, int) -> None Returns None and inserts the object <item> at the given <priority> User can have duplicate objects at the same or at different priorities ''' # in all scenarios we have to make a new node. Making a new wacky node # that points to none. We then have to assign new pointers to it and # make it part of the linked list family new_node = WackyNode(item, priority) # here comes the hard part! The part where pictures came in handy # thanks Nick for the drawing tip! Also, pri = priority in short :) # initialize curr to the head of the odd list curr = self._odd_list.get_next() after = self._even_list.get_next() # if curr is none, that is the odd list is empty if (curr is None): # then make the odd list point to the new node self._odd_list.set_next(new_node) # else if after in None, that is the even list is empty elif (after is None): # then add the new node to the even list self._even_list.set_next(new_node) # have a while loop that loops through the entire queue and looks # if the pri fits any of these case while (curr is not None) and (after is not None): # four cases: # 1- the general case, curr > insert > after if (curr.get_priority() > priority) and \ (priority > after.get_priority()): # then curr and after don't get changed curr = curr # this is causing the infinite loop after = after # the insert pointer algorithm: tho this will be repeated many # times in this function, only one of them will be executed # because of the elif structure # make curr point to the new node curr.set_next(new_node) # make after point to curr.next after.set_next(curr.get_next()) # make new node point to after.next new_node.set_next(after.get_next()) # 2- edge case: insert > curr elif (priority > curr.get_priority()): # then set after to be curr after = curr # and curr to be None curr = None # here our insert pointer algorithm will not work, because # None.any_method() will raise an exception # so here's the modified version of it: # since we're inserting at the head of the list, it will always # be inserted at the head of the odd list # make the head of the odd list point to the new node self._odd_list.set_next(new_node) # make head of the even point to the first node of odd self._even_list.set_next(after) # make the new node point to the first node of even new_node.set_next(after.get_next()) # 3- multiple entries of the same pri elif (priority == curr.get_priority()): # this is super messy, but let's do it! find a priority that # is less than the one we have while not (after.get_priority() < priority): # crashes whn\en after becomes None # set curr = after and after to the next node after curr curr, after = after, curr.get_next() # 4- edge case: curr = None elif (curr is None): # then insert the new node at the end curr.set_next(new_node) # if they fit none of these cases, get new currs and afters else: curr, after = after, curr.get_next()
def insert(self, obj, priority): '''(WackyQueue, obj, int) -> None Inserts an item named obj with priority given into the WackyQueue. If an item already exists with the same priority, the earlier item goes first in the WackyQueue. The way insert functions is that when we insert an element, all the elements that come after it are swapped from their current linked list to the other one. Let's take a look at an example: Odd List: [A] -> [D]-> [F]->[H] Even List: [B] -> [E] -> [G] Now let's say we want to insert C, the lists Become: Odd List: [A]->[C]->[E]->[G] Even List: [B]->[D]->[F]->[H] Notice how elements {D, F, H} that were originally in the odd list swapped to the even list, and elements {E,G} that were originally in the even list swapped to the odd list. In the code, we usually only have to make 1 swap however, because D would point to F which points to H, etc... and E would point to G, etc.... ''' # creating a new node that we're gonna insert into either # the odd linked list or the even linked list Node = WackyNode(obj, priority) # initializing some variables to keep track of the current # objects in the even and odd lists we're looking at. currentOdd, currentEven = self._oddListHead, self._evenListHead # Let's also initialize some variables to keep track of the previous # values, because sometimes we'll need to modify them and the # list is only singly linked previousOdd, previousEven = None, None # make a flag variable so that we know when to stop the loop # if we've found the correct spot to insert spotFound = False # in the case where the head of the even list is none (IE: empty) if currentEven == None: # in case the odd and even list are none (so the queue is completely empty) # we need to make the node the head of the odd list (because its the first element) # and indicate that we've found a spot if currentOdd == None: self._oddListHead = Node spotFound = True else: # now we branch off into two other cases # if the element has priority greater than the # largest element and the lists arent empty, we need # to swap the values of the even and odd lists, and # set the node to the highest value if priority > self._oddListHead.get_priority(): self._evenListHead = self._oddListHead self._oddListHead = Node spotFound = True # if the Queue contains only 1 element, we can # set the head of the even list as the node # and change the flag elif priority <= self._oddListHead.get_priority(): self._evenListHead = Node spotFound = True # in the case where the element to insert is the largest in the queue # and the list isn't empty we need to swap the heads of the lists # and set the item as the first in the Queue, also make sure # that the new item points to the old head of the odd list if currentOdd != None and currentEven != None: if priority > currentOdd.get_priority(): (self._oddListHead, self._evenListHead) = (self._evenListHead, self._oddListHead) Node.set_next(self._oddListHead) self._oddListHead = Node spotFound = True # initialize a counter so that we know whether to increment through the odd list or the # even list counter = 0 # the following loop tries to find a spot to place the new element # while we're not at the end of both lists and the flag hasn't # been set to true(which would mean that we've already found a spot) while currentOdd != None and currentEven != None and not spotFound: # the following cases account for the cases where we're at the end # of one or both lists if currentEven.get_next() == None: if currentOdd.get_next() == None: # if we're at the end of both lists and the element is less than both the last # elements in each list, we need to set the last element in the WackyQueue to the # node, and change the flag if priority <= currentOdd.get_priority( ) and priority <= currentEven.get_priority(): currentOdd.set_next(Node) spotFound = True # if we're at the last element in the even list but there's still an element in the odd list # we need to set the element to the next even and change the flag else: if priority <= currentOdd.get_next().get_priority(): currentEven.set_next(Node) spotFound = True # in the case where we're looking in the middle of the lists and we still haven't found a place to # insert our new element if spotFound == False: # in the case where our current element is between the element we're looking at in the even # list and odd list, we need to link the element inside the even list while switching the even # and odd elements that come after it.In all cases, change the flag if currentEven.get_priority( ) <= priority <= currentOdd.get_priority(): if previousEven != None: previousEven.set_next(Node) Node.set_next(currentOdd.get_next()) currentOdd.set_next(currentEven) # in the case where the even element is the head, we need # to set the head of the even list to the new element. if currentEven == self._evenListHead: self._evenListHead = Node spotFound = True # this case is also where the current element is between our current even and odd element, but the odd # element is greater and the even element is smaller, we perform the exact same operations as above, but # using the opposite list as above. we also dont need to do any checking for if we're dealing with the # heads of the lists because we would have dealt with this outside the while loop. if currentOdd.get_priority( ) <= priority < currentEven.get_priority(): previousOdd.set_next(Node) Node.set_next(currentEven.get_next()) currentEven.set_next(currentOdd) spotFound = True # the following statements increment our values to check in the odd and even lists # we need to make sure that we're not just looking at the n'th elements in each list # because we need to compare the nth value of the odd list with the nth value in the even # list, and then the nth value of the odd list with the n+1th value in the even list, etc... # so we make it so that on every even number, the values in the odd list will be incremented, # and on every odd number, the values in the even list will be incremented. Obviously, increment # the counter itself as well if counter % 2 == 0: previousOdd = currentOdd currentOdd = currentOdd.get_next() else: previousEven = currentEven currentEven = currentEven.get_next() counter += 1
def __init__(self): self._oddlist = WackyNode(None, None) # dummy node self._evenlist = WackyNode(None, None)