Exemple #1
0
def add_to_back(alist, val):
    """
    Purpose
        Insert val into alist at the end of the node chain
    Preconditions:
        :param alist: a list created by create()
        :param val:   a value of any kind
    Post-conditions:
        The list increases in size.
        The new value is last in the list.
    Return:
        :return None
    """

    if size(alist) == 0:
        new_node = node.create(val, None)
        alist['head'] = new_node
        alist['tail'] = new_node
        alist['size'] += 1
    else:
        cur_last_node = alist['tail']
        new_node = node.create(val, None)
        node.set_next(cur_last_node, new_node)
        alist['tail'] = new_node
        alist['size'] += 1
    return None
Exemple #2
0
def reverse_a(chain):
    """
    Purpose
        Reverse the sequence of the nodes in the given chain.
    Preconditions:
        :param chain: a node chain
    Post-conditions:
        The values in the chain are in the reversed order.
    Return:
        :return: the reversed node chain
    """

    if chain is None:
        return None
    elif node.get_next(chain) is None:
        return chain
    else:
        # remember the first two nodes
        first = chain
        second = node.get_next(chain)
        # reverse the chain starting at the second node
        reved = reverse_a(second)
        # second is now last!  hook the first node
        node.set_next(second, first)
        node.set_next(first, None)
        return reved
Exemple #3
0
def copy(node_chain, new_chain=None, head=None):
    """
    Purpose:
        Create a new node-chain
    Pre-conditions:
        :param node_chain: a node chain, possibly empty
    return:
        :return: a seperate distinct chain that has the same values as node-chain
    """

    if node_chain is None:
        if new_chain is None:
            return None
        node.set_next(new_chain, None)
        return head
    else:
        value = node.get_data(node_chain)
        if new_chain is None:
            new_chain = node.create(value, None)
            head = new_chain
            return copy(node.get_next(node_chain), new_chain, head)
        else:
            node.set_next(new_chain, node.create(value))
            return copy(node.get_next(node_chain), node.get_next(new_chain),
                        head)
Exemple #4
0
def remove_chain(node_chain, val):
    """
    Purpose:
        Remove the first occurrence of val from node_chain.
    Pre-conditions:
        :param node_chain: a node chain, possibly empty
        :param val: a value to be removed
    Post-conditions:
        The first occurrence of the value is removed from the chain.
        If val does not appear, the node-chain is unmodified.
    Return:
        :return: The resulting node chain with val removed
    """
    # special case: empty node chain
    if node_chain is None:
        return None

    # special case: node to be removed is first
    if node.get_data(node_chain) == val:
        return node.get_next(node_chain)

    # walk along the chain
    walker = node.get_next(node_chain)
    prev = node_chain
    while walker is not None and node.get_data(walker) != val:
        prev = walker
        walker = node.get_next(walker)

    # found first occurrence of val?
    if walker is not None:
        node.set_next(prev, node.get_next(walker))

    return node_chain
Exemple #5
0
def reverse_chain(node_chain):
    """
    Purpose:
        Completely reverses the order of the given node_chain.
    Pre-conditions:
        :param node_chain: a node chain, possibly empty
    Post-conditions:
        The front of the node_chain is altered to be the back, with all nodes now pointing next the opposite direction.
    Return:
        :return: The resulting node chain that has had its order reversed
    """

    #if node_chain is not a single node or empty, step through and reverse
    if a5q2.count_chain(node_chain) > 1:
        cur_node = node_chain
        prev_node = None
        next_node = node.get_next(node_chain)

        #step through and reverse each node
        while True:
            node.set_next(cur_node, prev_node)
            prev_node = cur_node
            cur_node = next_node

            #If next_node is None break, otherwise, move next to next node
            if next_node is None:
                break
            else:
                next_node = node.get_next(next_node)

        node_chain = prev_node

    return node_chain
Exemple #6
0
def remove_from_back(alist):
    """
    Purpose
        Removes and returns the last value in alist
    Preconditions:
        :param alist: a list created by create()
    Post-conditions:
        The list decreases in size.
        The returned value is no longer in in the list.
    Return:
        :return The pair True, value if alist is not empty
        :return The pair False, None if alist is empty
    """
    if is_empty(alist):
        return False, None

    if size(alist) == 1:
        anode = alist['head']
        alist['head'] = None
        alist['tail'] = None
        alist['size'] = 0
        return True, node.get_data(anode)

    # general case
    aprev = alist['head']
    anode = node.get_next(aprev)
    while node.get_next(anode) is not None:
        aprev = anode
        anode = node.get_next(anode)

    alist['tail'] = aprev
    node.set_next(aprev, None)
    alist['size'] -= 1
    return True, node.get_data(anode)
Exemple #7
0
def reverse_b(to_reverse, reversed=None):
    """
    Purpose
        Move all of the nodes in to_reverse to reversed
    Preconditions:
        :param to_reverse: a node chain to be reversed
        :param reversed: a node chain already reversed
    Post-conditions:
        to_reverse is reversed
    Return:
        :return: the resulting node chain with all nodes
    """

    # "pop" off a node from q, push it on s
    if to_reverse == None:
        return reversed
    else:
        # conceptually, grab the first node in to_reverse
        this_node = to_reverse
        # conceptually, grab the nodes after the first
        the_rest = node.get_next(this_node)
        # connect the first node to the ones that are already reversed
        node.set_next(this_node, reversed)
        # recursively reverse all the rest
        return reverse_b(the_rest, this_node)
Exemple #8
0
 def push(self, node):
     if self.currentNode == None:
         self.currentNode = node
         #self.set_next(None)
     else:
         node.set_next(self.currentNode)
         self.currentNode = node
Exemple #9
0
def delete_item_at_index(alist, idx):
    """
    Purpose
        Delete the value at index idx in alist.
    Preconditions:
        :param alist: a list created by create()
        :param idx:   a non-negative integer
    Post-conditions:
        The list decreases in size if the index is valid
        The value at idx is no longer in the list.
    Return:
        :return True if index was valid, False otherwise
    """
    if idx < 0 or idx >= size(alist):
        return False

    if idx == 0:
        remove_from_front(alist)
        return True

    if idx == size(alist) - 1:
        remove_from_back(alist)
        return True

    # general case
    anode = alist['head']
    aprev = None
    i = 0
    while anode is not None and i < idx:
        aprev = anode
        anode = node.get_next(anode)
        i += 1
    node.set_next(aprev, node.get_next(anode))
    alist['size'] -= 1
    return True
Exemple #10
0
def remove_from_back(alist):
    """
    Purpose
        Removes and returns the last value in alist
    Preconditions:
        :param alist: a list created by create()
    Post-conditions:
        The list decreases in size.
        The returned value is no longer in in the list.
    Return:
        :return The tuple (True, value) if alist is not empty
        :return The tuple (False, None) if alist is empty
    """
    if alist["tail"] is None:
        return False, None
    val = node.get_data(alist["tail"])
    if size(alist) is 1:  #singleton
        alist["head"] = None
        alist["tail"] = None
        alist["size"] -= 1
        return True, val
    walker = alist["head"]
    count = 1
    while count < size(alist) - 1:  #point walker to second last node
        walker = node.get_next(walker)
        count += 1
    node.set_next(walker, None)
    alist["tail"] = walker
    alist["size"] -= 1
    return True, val
Exemple #11
0
def delete_item_at_index(alist, idx):
    """
    Purpose
        Delete the value at index idx in alist.
    Preconditions:
        :param alist: a list created by create()
        :param idx:   a non-negative integer
    Post-conditions:
        The list decreases in size if the index is valid
        The value at idx is no longer in the list.
    Return:
        :return True if index was valid, False otherwise
    """
    if idx >= alist["size"] or idx < 0:  #if index out of range
        return False
    if idx is 0:  #if remove from front
        remove_from_front(alist)
        return True
    elif idx is size(alist) - 1:  #if remove from rear
        remove_from_back(alist)
        return True
    walker = node.get_next(alist["head"])  #all other cases
    previous = alist["head"]
    index = 1
    while True:
        if index == idx:
            node.set_next(previous, node.get_next(walker))
            alist["size"] -= 1
            return True
        walker = node.get_next(walker)
        previous = node.get_next(previous)
        index += 1
Exemple #12
0
def copy_chain(node_chain):
    """
    Purpose:
        Make a new node chain with the same values as in node_chain.
    Pre-conditions:
        :param node_chain: a node chain, possibly None
    Return:
        :return: A copy of node chain, with new nodes, but the same data.
    """
    # special case: empty node chain
    if node_chain is None:
        return None
    else:
        walker = node_chain

        # remember the first node
        result = node.create(node.get_data(walker))
        walker = node.get_next(walker)
        walker2 = result

        # walk along the first chain, making copies of each node
        while walker is not None:
            node.set_next(walker2, node.create(node.get_data(walker)))
            walker2 = node.get_next(walker2)
            walker = node.get_next(walker)

        # return the anchor to the copy
        return result
Exemple #13
0
def reverse_c(chain):
    """
    Purpose
        Reverse the sequence of the nodes in the given chain.
    Preconditions:
        :param chain: a node chain
    Post-conditions:
        The values in the chain are in the reversed order.
    Return:
        :return: the reversed node chain
    """

    if chain is None:
        return None
    elif node.get_next(chain) is None:
        return chain
    else:
        # remember the first two nodes
        first = chain
        second = node.get_next(chain)
        # reverse the chain starting at the second node
        reved = reverse_c(second)
        walker = reved
        prev = None
        while walker is not None:
            prev = walker
            walker = node.get_next(walker)
        if prev is not None:
            node.set_next(prev, first)
            node.set_next(first, None)
        return reved
Exemple #14
0
def extend(alist, blist):
    """
    Purpose
        append all the nodes in blist on the end of alist
    Preconditions:
        :param alist: a list created by create()
        :param blist: a list created by create()
    Post-conditions:
        alist has all the nodes of blist appended to it
        alist's tail is the same as blist's tail
        alist's size = alist's size + blist's size
    Return:
        None
    """

    if is_empty(alist) and is_empty(blist):
        pass
    elif is_empty(alist):
        alist = blist
    elif is_empty(blist):
        pass
    else:
        atail = alist['tail']
        node.set_next(atail, blist['head'])
        alist['tail'] = blist['tail']
        alist['size'] += blist['size']
Exemple #15
0
def delete_item_at_index(alist, idx):
    """
    Purpose
        Delete the value at index idx in alist.
    Preconditions:
        :param alist: a list created by create()
        :param idx:   a non-negative integer
    Post-conditions:
        The list decreases in size if the index is valid
        The value at idx is no longer in the list.
    Return:
        :return True if index was valid, False otherwise
    """

    #check if idx is within scope of alist or check if alist is empty
    if alist['size'] - idx < 1 or is_empty(alist):
        return False

    #check if list is a singleton
    elif alist['size'] == 1:
        remove_from_front(alist)
        return True

    #check if idx is the first index
    elif idx == 0:
        remove_from_front(alist)
        return True

    #check if idx is the last index
    elif alist['size'] - idx == 1:
        remove_from_back(alist)
        return True

    #general case
    else:
        cur_node = alist['head']
        next_node = node.get_next(cur_node)
        next_idx = 1

        while next_node is not None:
            if next_idx == idx:
                after_next = node.get_next(next_node)
                node.set_next(cur_node, after_next)
                alist['size'] -= 1
                return True
            else:
                cur_node = next_node
                next_node = node.get_next(next_node)
                next_idx += 1
Exemple #16
0
def insert_value_at_index(alist, val, idx):
    """
    Purpose
        Insert val into alist at index idx
    Preconditions:
        :param alist: a list created by create()
        :param val:   a value of any kind
        :param idx:   a valid index for the list
    Post-conditions:
        The list increases in size.
        The new value is at index idx.
        The values previously in the list at idx or later appear after the new value.
    Return:
        :return If the index is valid, insert_value_at_index returns True.
        :return If the index is not valid, insert_value_at_index returns False.
    """

    #check if idx beyond alist['size'] + 1 or idx is negative, return False
    if alist['size'] - idx < 0 or idx < 0:
        return False

    #if index is the first index or is empty, add new val at the front
    if idx == 0 or is_empty(alist):
        add_to_front(alist, val)
        return True

    #if index is immediately after the last index of alist, add new val to back
    elif idx == alist['size']:
        add_to_back(alist, val)
        return True

    #general case
    else:
        cur_node = alist['head']
        next_node = node.get_next(cur_node)
        next_idx = 1  #index of next_node

        while next_node is not None:
            if next_idx == idx:
                new_node = node.create(val, next_node)
                node.set_next(cur_node, new_node)
                alist['size'] += 1
                return True
            else:
                cur_node = next_node
                next_node = node.get_next(next_node)
                next_idx += 1
Exemple #17
0
def reverse_chain(node_chain, prev_node=None):
    """
    Purpose:
        Completely reverses the order of the given node_chain.
    Pre-conditions:
        :param node_chain: a node chain, possibly empty
    Post-conditions:
        The front of the node_chain is altered to be the back, with all nodes now pointing next the opposite direction.
    Return:
        :return: The resulting node chain that has had its order reversed
    """
    if node_chain is None:
        return prev_node
    else:
        next = node.get_next(node_chain)
        node.set_next(node_chain, prev_node)
        return reverse_chain(next, node_chain)
Exemple #18
0
def copy(chain):
    """
    Purpose
        Make a completely new copy of the given node-chain.
    Preconditions:
        :param chain: a node-chain
    Post-conditions:
        None
    Return:
        :return: A new copy of the chain is returned
    """
    if chain == None:
        return None
    else:
        newnode = node.create(node.get_data(chain))
        newnext = copy(node.get_next(chain))
        node.set_next(newnode, newnext)
        return newnode
Exemple #19
0
def remove_from_back(alist):
    """
    Purpose
        Removes and returns the last value in alist
    Preconditions:
        :param alist: a list created by create()
    Post-conditions:
        The list decreases in size.
        The returned value is no longer in in the list.
    Return:
        :return The tuple (True, value) if alist is not empty
        :return The tuple (False, None) if alist is empty
    """
    #check if linked list is already EMPTY
    if is_empty(alist):
        return False, None

    #check if linked list is a singleton
    elif size(alist) == 1:
        node_to_remove = alist['head']
        removed_data = node.get_data(
            node_to_remove)  #data to be removed and returned
        alist['head'] = None
        alist['tail'] = None
        alist['size'] = 0
        return True, removed_data

    else:
        prev_node = alist['head']
        next_node = node.get_next(prev_node)

        while next_node is not None:
            #if next_node is the same as tail, then prev_node becomes the new tail
            if next_node == alist['tail']:
                removed_data = node.get_data(
                    next_node)  #data to be removed and returned
                node.set_next(prev_node, None)
                alist['tail'] = prev_node
                alist['size'] -= 1
                return True, removed_data
            else:
                prev_node = next_node
                next_node = node.get_next(next_node)
Exemple #20
0
def add_to_back(alist, val):
    """
    Purpose
        Insert val into alist at the end of the node chain
    Preconditions:
        :param alist: a list created by create()
        :param val:   a value of any kind
    Post-conditions:
        The list increases in size.
        The new value is last in the list.
    Return:
        :return None
    """
    anode = node.create(val)
    if is_empty(alist):
        alist['head'] = anode
    else:
        node.set_next(alist['tail'], anode)
    alist['tail'] = anode
    alist['size'] += 1
Exemple #21
0
def insert_value_at_index(alist, val, idx):
    """
    Purpose
        Insert val into alist at index idx
    Preconditions:
        :param alist: a list created by create()
        :param val:   a value of any kind
        :param idx:   a valid index for the list
    Post-conditions:
        The list increases in size.
        The new value is at index idx.
        The values previously in the list at idx or later appear after the new value.
    Return:
        :return If the index is valid, insert_value_at_index returns True.
        :return If the index is not valid, insert_value_at_index returns False.
    """
    if idx > alist["size"] or idx < 0:  #if index out of range
        return False
    new = node.create(val)
    if alist["head"] is None and idx is 0:  #if empty list
        add_to_front(alist, val)
        return True
    else:
        if idx is 0:  #if add to front
            add_to_front(alist, val)
            return True
        if idx is size(alist):  #if add to rear: idx is the same as size
            add_to_back(alist, val)
            return True
    walker = node.get_next(alist["head"])
    previous = alist["head"]
    index = 1
    while True:  #add in between
        if index == idx:
            node.set_next(previous, new)
            node.set_next(new, walker)
            alist["size"] += 1
            return True
        walker = node.get_next(walker)
        previous = node.get_next(previous)
        index += 1
Exemple #22
0
def split_chain(node_chain):
    """
    Purpose:
        Splits the given node chain in half, returning the second half.
        If the given chain has an odd length, the extra node is part of
        the second half of the chain.
    Pre-conditions:
        :param node_chain: a node-chain, possibly empty
    Post-conditions:
        the original node chain is cut in half!
    Return:
        :return: A tuple (nc1, nc2) where nc1 and nc2 are node-chains
         each containing about half of the nodes in node-chain
    """
    # calculate size
    n = a5q2.count_chain(node_chain)

    # special case: empty chain
    if n == 0:
        return None, None
    # special case: chain with one node
    if n == 1:
        return None, node_chain

    # calculate halfway
    mid = n // 2

    # walk along the chain until half-way
    walker = node_chain
    prev = None
    counter = 0
    while counter < mid:
        prev = walker
        walker = node.get_next(walker)
        counter += 1

    # terminate the first half with a well-placed None
    node.set_next(prev, None)

    # return the two new chains
    return node_chain, walker
Exemple #23
0
def add_to_back(alist, val):
    """
    Purpose
        Insert val into alist at the end of the node chain
    Preconditions:
        :param alist: a list created by create()
        :param val:   a value of any kind
    Post-conditions:
        The list increases in size.
        The new value is last in the list.
    Return:
        :return None
    """
    new = node.create(val)
    if alist["tail"] is None:
        alist["head"] = new
        alist["tail"] = new
    else:
        node.set_next(alist["tail"], new)
        alist["tail"] = new
    alist["size"] += 1
Exemple #24
0
def insert_at(node_chain, value, index):
    """
    Purpose:
        Insert the given value into the node-chain so that
        it appears at the the given index.
    Pre-conditions:
        :param node_chain: a node-chain, possibly empty
        :param value: a value to be inserted
        :param index: the index where the new value should appear
        Assumption:  0 <= index <= n
                     where n is the number of nodes in the chain
    Post-condition:
        The node-chain is modified to include a new node at the
        given index with the given value as data.
    Return
        :return: the node-chain with the new value in it
    """

    # special case: insert at index 0
    if index == 0:
        return node.create(value, node_chain)

    # walk along the chain until the indicated index
    walker = node_chain
    counter = 0
    prev = None
    while walker is not None and counter < index:
        prev = walker
        walker = node.get_next(walker)
        counter += 1

    # If there is a node at the index
    if counter == index:
        # insert a new node
        node.set_next(prev, node.create(value, walker))
    else:
        # insert at the very end
        node.set_next(prev, node.create(value, None))

    return node_chain
Exemple #25
0
def insert_value_sorted(node_chain, number_value):
    """
    Purpose:
        Insert the given number_value into the node-chain so that it appears after a previous value that is <= value. If the node_chain was empty, new value is simply placed at the front.
    Pre-conditions:
        :param node_chain: a node-chain, possibly empty, containing only numbers
        :param number_value: a numerical value to be inserted
        Assumption:  node_chain only contains numbers (which can be compared to the given number_value)
    Post-condition:
        The node-chain is modified to include a new node with number_value as its data after a previous node's data value is <= number_value.
    Return
        :return: the node-chain with the new value in it
    """

    #if the node chain is empty, add the new node
    if a5q2.count_chain(node_chain) < 1:
        node_chain = node.create(number_value, None)

    #if chain is not empty, find the proper place
    else:
        cur_node = node_chain
        prev_node = None
        next_node = node.get_next(node_chain)

        while True:
            cur_val = node.get_data(cur_node)

            #check if the value should be placed in front of current node
            if cur_val == number_value + 1:
                #check if the target node is the first node
                if prev_node == None:
                    node_chain = node.create(number_value, cur_node)
                else:
                    new_node = node.create(number_value, cur_node)
                    node.set_next(prev_node, new_node)
                break

            #check if the value should be placed after the current node
            if cur_val == number_value - 1:
                #check if target node is the last node in chain
                if next_node == None:
                    new_node = node.create(number_value, None)
                    node.set_next(cur_node, new_node)
                else:
                    new_node = node.create(number_value, next_node)
                    node.set_next(cur_node, new_node)
                break

            #break if at the end of the node chain
            if next_node == None:
                break
            #move to next node if not at the end of the chain
            else:
                prev_node = cur_node
                cur_node = next_node
                next_node = node.get_next(next_node)

    return node_chain
Exemple #26
0
def enqueue(queue, value):
    """
    Purpose
        adds the given data value to the given queue
    Pre-conditions:
        queue: a queue created by create()
        value: data to be added
    Post-condition:
        the value is added to the queue
    Return:
        (none)
    """
    new_node = node.create(value, None)

    if is_empty(queue):
        queue['front'] = new_node
        queue['back'] = new_node
    else:
        prev_last_node = queue['back']
        node.set_next(prev_last_node, new_node)
        queue['back'] = new_node

    queue['size'] += 1
Exemple #27
0
def insert_value_at_index(alist, val, idx):
    """
    Purpose
        Insert val into alist at index idx
    Preconditions:
        :param alist: a list created by create()
        :param val:   a value of any kind
        :param idx:   a valid index for the list
    Post-conditions:
        The list increases in size.
        The new value is at index idx.
        The values previously in the list at idx or later appear after the new value.
    Return:
        :return If the index is valid, insert_value_at_index returns True.
        :return If the index is not valid, insert_value_at_index returns False.
    """
    if idx < 0 or idx > size(alist):
        return False

    if idx == 0:
        add_to_front(alist, val)
        return True

    if idx == size(alist):
        add_to_back(alist, val)
        return True

    # general case
    anode = alist['head']
    i = 1
    while anode is not None and i < idx:
        anode = node.get_next(anode)
        i += 1
    new_node = node.create(val, node.get_next(anode))
    node.set_next(anode, new_node)
    alist['size'] += 1
    return True
Exemple #28
0
# Remove the 3 from the sequence

chain = node.get_next(chain)

# Add 6 to the front

chain = node.create(6, chain)

# add 7 to the end
anode = node.create(7)

bnode = chain
while node.get_next(bnode) != None:
    bnode = node.get_next(bnode)

node.set_next(bnode, anode)

# Extra exercises:
# Exercise 1
# Display all numbers in the chain
# Turn this code into a function!
# chain-->[ 3 | *-]-->[ 2 | *-]-->[ 1 | *-]-->[ 5 | *-]-->[ 4 | / ]

# Exercise 2
# Count the even numbers
# chain-->[ 3 | *-]-->[ 2 | *-]-->[ 1 | *-]-->[ 5 | *-]-->[ 4 | / ]
# anode --------------------------^

# Exercise 3
# Check if the data values 2, 9 are in the chain
# Turn this code into a function!
Exemple #29
0
def insert_value_sorted(node_chain, number_value):
    """
    Purpose:
        Insert the given number_value into the node-chain so that it appears after a previous value that is <= value. If the node_chain was empty, new value is simply placed at the front.
    Pre-conditions:
        :param node_chain: a node-chain, possibly empty, containing only numbers
        :param number_value: a numerical value to be inserted
        Assumption:  node_chain only contains numbers (which can be compared to the given number_value)
    Post-condition:
        The node-chain is modified to include a new node with number_value as its data after a previous node's data value is <= number_value.
    Return
        :return: the node-chain with the new value in it
    """
    if node_chain == None:
        return node.create(number_value)
#1 node
    anode = node_chain
    current = node.get_data(anode)
    if number_value <= current:  #add to front, regardless of node size
        return node.create(number_value, anode)
    if node.get_next(anode) == None:  #add after
        node.set_next(anode, node.create(number_value))
        return anode
#2 nodes
    next1 = node.get_data(node.get_next(anode))
    if node.get_next(node.get_next(anode)) == None:
        if number_value <= next1:  #add in middle
            node.set_next(anode, node.create(number_value,
                                             node.get_next(anode)))
            return anode
        if number_value > next1:
            node.set_next(node.get_next(anode), node.create(number_value))
            return anode
#3+
    next1 = node.get_data(node.get_next(anode))
    while node.get_next(
            node.get_next(anode)) != None:  #step until the second last one
        if number_value > current and number_value <= next1:  #if larger than current and smaller than next
            node.set_next(anode, node.create(number_value,
                                             node.get_next(anode)))
            return node_chain
        anode = node.get_next(anode)
        current = node.get_data(anode)
        next1 = node.get_data(node.get_next(anode))
    if number_value <= next1:  #check last 2 values
        node.set_next(anode, node.create(number_value, node.get_next(anode)))
        return node_chain
    node.set_next(node.get_next(anode), node.create(number_value))
    return node_chain