简体   繁体   中英

Merging two sorted Doubly Linked Lists in python using recursion

I am trying to write a method that merges two sorted Doubly Linked Lists of integers, using recursion (it has to be recursive). The method creates and returns a new Doubly Linked List with the integer values in order. For example, if doublylinkedlist1 = [0-2-4] and doublylinkedlist2 = [1-3-5], the merge_sorted method would return [0-1-2-3-4-5].

However, when I run my code below:

class EmptyCollection(Exception):
pass


class DoublyLinkedList:
    class Node:
        def __init__(self, data=None, next=None, prev=None):
            self.data = data
            self.next = next
            self.prev = prev

        def disconnect(self):
            self.data = None
            self.next = None
            self.prev = None

    def __init__(self):
        self.header = DoublyLinkedList.Node()
        self.trailer = DoublyLinkedList.Node()
        self.header.next = self.trailer
        self.trailer.prev = self.header
        self.size = 0

    def __len__(self):
        return self.size

    def is_empty(self):
        return (len(self) == 0)

    def first_node(self):
        if (self.is_empty()):
            raise EmptyCollection("List is empty")
        return self.header.next

    def last_node(self):
        if (self.is_empty()):
            raise EmptyCollection("List is empty")
        return self.trailer.prev

    def add_first(self, elem):
        return self.add_after(self.header, elem)

    def add_last(self, elem):
        return self.add_after(self.trailer.prev, elem)

    def add_after(self, node, elem):
        prev = node
        succ = node.next
        new_node = DoublyLinkedList.Node()
        new_node.data = elem
        new_node.prev = prev
        new_node.next = succ
        prev.next = new_node
        succ.prev = new_node
        self.size += 1
        return new_node

    def add_before(self, node, elem):
        return self.add_after(node.prev, elem)

    def delete(self, node):
        prev = node.prev
        succ = node.next
        prev.next = succ
        succ.prev = prev
        self.size -= 1
        data = node.data
        node.disconnect()
        return data

    def __iter__(self):
        if(self.is_empty()):
            return
        cursor = self.first_node()
        while(cursor is not self.trailer):
            yield cursor.data
            cursor = cursor.next

    def __str__(self):
        return '[' + '<-->'.join([str(elem) for elem in self]) + ']'

    def __repr__(self):
        return str(self)




def merge_linked_lists(srt_lnk_lst1, srt_lnk_lst2):
    return merge_sublists(srt_lnk_lst1.first_node(), srt_lnk_lst2.first_node())


def merge_sublists(a, b):
    result = DoublyLinkedList()
    if a is not None and b is not None:
        if a.data < b.data:
            result.add_last(a.data)
            return merge_sublists(a.next, b)
        else:
            result.add_last(b.data)
            return merge_sublists(a, b.next)
    elif a is not None:
        result.add_last(a.data)
        return merge_sublists(a.next, b)
    elif b is not None:
        result.add_last(b.data)
        return merge_sublists(a, b.next)
    return result



ll1 = DoublyLinkedList()
for i in range(0,10,2):
    ll1.add_last(i)
ll2 = DoublyLinkedList()
for i in range(1,10,2):
    ll2.add_last(i)
merged = merge_linked_lists(ll1, ll2)
print(merged)

I get an error in my merge_sublists function that says I cannot add 'int' and 'Nonetype'.

Is there any way I can modify my merge_sublists method to make the function work properly? Any help is appreciated.

When you hit the end of the a list, although the object isn't None , you have a.data as None . You need to check the data as well as the list objects.

The problem is caused by the dummy list nodes that are placed at the start and end of the list. Although the code checks for empty lists, and skips over the initial dummy node, there is no check for the final dummy node at the end of the list. So while following a.next and b.next , it eventually encounters a dummy node, which has None as the value of data . The error occurs when it tries to compare None to the data value in another node.

You could check if a.next and b.next are None at the top of merge_sublists , but you will still need to make sure you only end up with a single dummy node at the end of the merged list.

It might be simplest to eliminate the dummy nodes altogether, and just check for an empty list when adding new nodes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM