我正在阅读Cracking the Coding Interview并且正在练习练习问题而且我仍然坚持这个:
“实现一种算法来删除中间的节点(即除了第一个和最后一个节点之外的任何节点,不一定是确切的中间节点)或单个链接列表,只能访问该节点。
实施例 输入:来自链表的节点a-> b-> c-> d-> e-> f 结果:未返回任何内容,但新链接列表看起来像a-> b-> d-> e-> f“
这是我的代码:
class Node:
def __init__(self, data = None, nextnode = None):
self.data = data
self.nextnode = nextnode
def __str__(self):
return str(self.data)
class LinkedList():
def __init__(self, head = None):
self.head = head
def insert(self, data):
new_node = Node(data)
new_node.nextnode = self.head
self.head = new_node
def remove(self, data):
current = self.head
absent = True
if current == None: print('List is empty')
if current.data == data:
self.head = current.nextnode
absent = False
while current.nextnode:
if current.nextnode.data == data:
absent = False
if current.nextnode.nextnode:
current.nextnode = current.nextnode.nextnode
else: current.nextnode = None
else: current = current.nextnode
if absent: print('Element not in list')
def size(self):
current = self.head
size = 0
while current:
current = current.nextnode
size += 1
return size
def find(self, data):
current = self.head
if current == None: print('List is empty')
search = True
while current and search:
if current.data == data:
print(current)
search = False
current = current.nextnode
if search: print('Not found')
def print_list(self):
current = self.head
while current:
print(current, end = ' ')
current = current.nextnode
print('')
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node1.nextnode = node2
node2.nextnode = node3
node3.nextnode = node4
list1 = LinkedList(node1)
list1.insert(2 ****EDITED node2 to 2 here****)
print_list(list1)
def delmid(ll, n):
current = ll.head
if current == n:
print('Can\'t delete first node')
return
while current.nextnode:
if current.nextnode == n:
if current.nextnode.nextnode:
current.nextnode = current.nextnode.nextnode
return
else:
print('Can\'t delete last node')
return
delmid(list1, node2)
print_list(list1)
我无法弄清楚为什么它似乎没有认为ll.head和node2是相同的......如果我摆脱了行list1.insert(node2)
...
我不明白......
编辑:在读完书中解决方案的第一句后,显然我做错了......“只允许访问该节点”意味着你不知道列表的头部...返回到绘图板......答案 0 :(得分:1)
因为你的插入方法错了:
def insert(self, data):
new_node = Node(data)
new_node.nextnode = self.head
self.head = new_node
您的方法不会插入node2
本身作为节点:它会创建一个新节点,其中node2
作为有效负载(数据)。这是不同的。
您可以定义方法:
def insert_node(self, node):
node.nextnode = self.head
self.head = new_node
然而,这将创建一个循环,因为现在node1
将指向node2
和node2 to
node1`。因此,生成的链表将是一个带有两个元素的圆形列表,如:
node1 --> node2
^---------/
编辑:因为你解决了那个问题。您的delmid
方法也存在问题。
主要问题是你的while
循环中的需要遍历链表,而你不这样做:当前总是保持不变,所以:
def delmid(ll, n):
current = ll.head
if current == n:
print('Can\'t delete first node')
return
while current.nextnode:
if current.nextnode == n:
if current.nextnode.nextnode:
current.nextnode = current.nextnode.nextnode
return
else:
print('Can\'t delete last node')
return
current = current.nextnode
应该解决这个问题。
答案 1 :(得分:0)
您误解了自己的insert
- 实施。
list1.insert(node2)
将node2
的新节点作为内容:
def insert(self, data):
new_node = Node(data) # <== wrap node2 into another node instance
new_node.nextnode = self.head
self.head = new_node
==
- 运算符通过调用方法__eq__(self, other)
在内部工作。在您的情况下,您没有为此方法提供和实现,因此默认值用于比较所有变量,其中包括nextnode
。因此,如果它们完全相同,则两个节点只能相等。要更正此问题,请使用Node
中的自定义比较方法:
def __eq__(self, other):
return type(other) is Node && other.data == self.data
此__eq__
- 方法首先检查other
肯定属于Node
类型,然后按每个实例中存储的data
进行比较。
比实际问题更进一步:
while current.nextnode:
if current.nextnode == n:
if current.nextnode.nextnode:
current.nextnode = current.nextnode.nextnode
return
else:
print('Can\'t delete last node')
return
此循环将无限运行,除非列表的最大大小为1.要在current = current.nextnode
列表中修复此步骤。
此任务的实际目的是让您习惯于另一种操纵链接列表的方式:交换。
您可以检查n
既不是第一个节点也不是最后一个节点,而是将值替换为连续节点的值,而不是在整个列表中搜索n
的前任。删除连续节点:
def delmid(ll, n):
if ll.head == n:
print('Can\'t delete first node')
return
if n.nextnode is None:
print('Can\'t delete last node')
return
# swap values
tmp = n.data
n.data = n.nextnode.data
n.nextnode.data = tmp
# remove node
n.nextnode = n.nextnode.nextnode