我怎么能把这个单链表放到一个双向链表中呢?

时间:2016-02-16 05:41:33

标签: python linked-list

我在Python中创建了一个链表,它是单链接的。这很好用,但我想实现它,因此它有双重联系,但我无法弄清楚如何去做。

# node class
class node:
    def __init__(self):
        self.data = None # contains the data
        self.next = None # contains the reference to the next node

# linked list class
class linked_list:
    def __init__(self):
        self.cur_node = None

    def add_node(self, data):
        new_node = node() # create a new node
        new_node.data = data
        new_node.next = self.cur_node # link the new node to the 'previous' node.
        self.cur_node = new_node # set the current node to the new one.

    def list_print(self):
        node = self.cur_node # cant point to ll!
        while node:
            print(node.data)
            node = node.next

我知道我需要将self.previous添加到节点类中,我想我需要在linked list构造函数和add_node函数中添加一些内容,但我不是确定从哪里开始。

我实际上并不需要在程序中使用此功能,我只是想了解如何在较低级别实现链接列表。

2 个答案:

答案 0 :(得分:1)

这不是一个编码问题,而是一个概念问题。您需要弄清楚您希望代码的行为方式。实现所需的行为(在这种情况下)并不困难。

说我们想要这些行为:

# construction
dlist = DoublyLinkedList()

# access to head and tail nodes
dlist.head  # should return the head node
dlist.tail  # should return the tail node

dlist.head.prev is None  # should be True
dlist.tail.next is None  # should be True 

# adding nodes at both ends
dlist.add_head()
dlist.add_tail()

# iteration in both directions
for node in dlist:
    # do something to the node
for node in reversed(dlist):
    # do something to the node

如果您已经写出了这样的预期行为,那么您还可以准备好一些测试代码。

现在让我们首先修改Node类(you should use CamelCase for class names):

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

    def __repr__(self):
        return '<{}, {}>'.format(self.data, self.next)

我们添加prev,因为显然需要这样做。但我们也通过将datanext作为参数来改进原始版本,因此您可以在创建节点时设置这些值。并且__repr__总是很好,如果没有其他任何东西的调试。

现在列表本身。关键是,(a)而不是一个cur_node,您需要列表中的两个句柄,我一直在调用headtail,以及(b)在添加节点时,第一个节点是一个特殊情况,我们必须对headtail进行更改。

class DoublyLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None

    def __repr__(self):
        return '<DoublyLinkedList {}>'.format(self.head)

    def add_head(self, data=None):
        if self.head is None:
            self.head = self.tail = Node(data)  # the very fist node
        else:
            new_head = Node(data=data, next=self.head)  # prev is None
            self.head.prev = self.head = new_head

    def add_tail(self, data=None):
        if self.tail is None:
            self.head = self.tail = Node(data)  # the very first node
        else:
            new_tail = Node(data=data, prev=self.tail)  # next is None
            self.tail.next = self.tail = new_tail

    # implements iteration from head to tail
    def __iter__(self):
        current = self.head
        while current is not None:
            yield current
            current= current.next

    # implements iteration from tail to head
    def __reversed__(self):
        current = self.tail
        while current  is not None:
            yield current
            current = current.prev

我们来试试这个

>>> dlist = DoublyLinkedList()
>>> print(dlist)
<DoublyLinkedList None>
>>> dlist.add_head(1)
>>> dlist.add_tail(2)
>>> dlist.add_tail(3)
>>> dlist.add_head(0)
>>> print(dlist)  # __repr__ is such a nice thing to have
<DoublyLinkedList <0, <1, <2, <3, None>>>>>
>>> print(dlist.head)
<0, <1, <2, <3, None>>>>
>>> print(dlist.tail)
<3, None>
>>> print(dlist.head.prev is None, dlist.tail.next is None)
True, True
>>> print(dlist.tail.prev.next is dlist.tail)
True
>>> [node.data for node in dlist]
[0, 1, 2, 3]
>>> for node in reversed(dlist):
...     print(node.data, node)
3 <3, None>
2 <2, <3, None>>
1 <1, <2, <3, None>>>
0 <0, <1, <2, <3, None>>>>

答案 1 :(得分:0)

对于双向链表,您应该拥有,每个节点都应该具有对前一节点的引用。这意味着您需要修改添加和删除方法以分配此引用。