我在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
函数中添加一些内容,但我不是确定从哪里开始。
我实际上并不需要在程序中使用此功能,我只是想了解如何在较低级别实现链接列表。
答案 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
,因为显然需要这样做。但我们也通过将data
和next
作为参数来改进原始版本,因此您可以在创建节点时设置这些值。并且__repr__
总是很好,如果没有其他任何东西的调试。
现在列表本身。关键是,(a)而不是一个cur_node
,您需要列表中的两个句柄,我一直在调用head
和tail
,以及(b)在添加节点时,第一个节点是一个特殊情况,我们必须对head
和tail
进行更改。
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)
对于双向链表,您应该拥有,每个节点都应该具有对前一节点的引用。这意味着您需要修改添加和删除方法以分配此引用。