使用递归在python中合并两个已排序的双链接列表

时间:2017-11-03 19:38:47

标签: python algorithm recursion doubly-linked-list

我正在尝试编写一个方法,使用递归(它必须是递归的)合并两个排序的整数双链表。该方法按顺序创建并返回带有整数值的新的双向链表。例如,如果doublylinkedlist1 = [0-2-4]和doublylinkedlist2 = [1-3-5],merge_sorted方法将返回[0-1-2-3-4-5]。

但是,当我在下面运行我的代码时:

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)

我的merge_sublists函数中出现错误,表示我无法添加'int'和'Nonetype'。

有什么方法可以修改我的merge_sublists方法以使函数正常工作?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:0)

当您点击a列表的末尾时,虽然该对象不是None,但您a.dataNone。您需要检查数据以及列表对象。

答案 1 :(得分:0)

问题是由放置在列表开头和结尾的虚拟列表节点引起的。虽然代码检查空列表,并跳过初始虚节点,但是没有检查列表末尾的最终虚节点。因此,在跟随a.nextb.next时,它最终会遇到一个虚拟节点,其None的值为data。尝试将None与另一个节点中的数据值进行比较时发生错误。

您可以在a.next的顶部检查b.nextNonemerge_sublists,但是您仍然需要确保只有一个虚拟对象合并列表末尾的节点。

完全消除虚节点可能是最简单的,只需在添加新节点时检查空列表。