[英]Doubly Linked list in Python
嗨,我真的迷路了。 我正在为我的数据结构类编写一个“双链表”程序,但我无法弄清楚。
更新:所以我完成了单链列表分配。 如何将其转换为双向链表,并使用提供的数据将其加载并打印出来?
程序规格:
从控制台读取15个人的名称和权重数据,在该行上有一个名称,然后在下一行有一个权重,例如names.txt。
您的程序将通过双向链接列表为基于名称和权重的升序维护的数据建立一个列表。
该dll将使用一个指针将权重保持在已排序的顺序,并使用另一个链接将名称保持在已排序的顺序。
您需要在保持此顺序的同时构建列表,因此在任何时候调用print方法都会按顺序打印相关字段。 (这意味着节点将按已排序的顺序添加到列表,元素不会添加到列表,后跟列表上调用的排序。)
例如,在为(名称–权重)添加3个元素之后:迈克尔– 275,汤姆– 150,安倍– 200。
输出:名称和权重按名称排序(升序)。 :安倍– 200,迈克尔– 275,汤姆-150名称和重量按重量排序(升序)。 :汤姆-150,安倍-200,迈克尔-275
class LinkedList(object):
__slots__ = 'prev', 'next', 'value'
ll1 = LinkedList()
ll2 = LinkedList()
if __name__=="__main__":
f = open("Names.txt","r")
ll1.value = f.readline()
ll1.next = ll2
ll1.prev = None
ll2.value = f.readline()
ll2.next = None
ll2.prev = ll1
f.close()
print("Linearly: \n")
print(ll1.value)
print(ll1.next.value)
print("Reversely: \n")
print(ll2.value)
print(ll2.prev.value)
#!/usr/bin/env python
class Node:
def __init__(self):
self.data = None
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def addNode(self, data):
curr = self.head
if curr is None:
n = Node()
n.data = data
self.head = n
return
if curr.data > data:
n = Node()
n.data = data
n.next = curr
self.head = n
return
while curr.next is not None:
if curr.next.data > data:
break
curr = curr.next
n = Node()
n.data = data
n.next = curr.next
curr.next = n
return
def __str__(self):
data = []
curr = self.head
while curr is not None:
data.append(curr.data)
curr = curr.next
return "[%s]" %(', '.join(str(i) for i in data))
def __repr__(self):
return self.__str__()
if __name__=="__main__":
ll = LinkedList()
num = int(input("Enter a number: "))
while num != -1:
ll.addNode(num)
num = int(input("Enter a number: "))
c = ll.head
while c is not None:
print(c.data)
c = c.next
Jim
150
Tom
212
Michael
174
Abe
199
Richard
200
April
117
Claire
124
Bobby
109
Bob
156
Kevin
145
Jason
182
Brian
150
Chris
175
Steven
164
Annabelle
99
如您所见,我没有做太多事情。 我不确定如何正确加载数据,但总体上我迷失了。 我不确定从哪里开始。 我在网上看了几个例子,但它们对我来说只是个谜。
感谢您的任何帮助。 我非常感谢。
这就是我要怎么做。 我建议您创建一个新问题或搜索如何从文本文件中读取数据。
class Node:
def __init__(self, name, weight):
self.name = name
self.weight = weight
self.prev_name = None
self.next_name = None
self.prev_weight = None
self.next_weight = None
class DLL:
def __init__(self):
self.head = Node(None, None)
self.tail = Node(None, None)
self.head.next_name = self.tail
self.head.next_weight = self.tail
self.tail.prev_name = self.head
self.tail.prev_weight = self.head
def add(self, name, weight):
node = Node(name, weight)
# add by name
p = self.head
while (p.next_name != self.tail) and (p.next_name.name < name):
p = p.next_name
node.next_name = p.next_name
node.prev_name = p
p.next_name = node
node.next_name.prev_name = node
# add by weight
p = self.head
while (p.next_weight != self.tail) and (p.next_weight.weight < weight):
p = p.next_weight
node.next_weight = p.next_weight
node.prev_weight = p
p.next_weight = node
node.next_weight.prev_weight = node
def printByName(self):
p = self.head
while p.next_name != self.tail:
print(p.next_name.name, p.next_name.weight)
p = p.next_name
def printByWeight(self):
p = self.head
while p.next_weight != self.tail:
print(p.next_weight.name, p.next_weight.weight)
p = p.next_weight
return
和一些结果:
D = DLL()
D.add("Jim",150)
D.add("Tom",212)
D.add("Michael",174)
D.add("Abe",199)
D.printByName()
Abe 199
Jim 150
Michael 174
Tom 212
D.printByWeight()
Jim 150
Michael 174
Abe 199
Tom 212
考虑到问题定义指定了“指针”这一事实,因此python不适合用于实现此目的。 但是您可以将python变量用作“指针”(或引用 ),因为它们就是它们。 python变量只是对象的名称或名称。
但是,如果您想在python中实现,我将使用列表ot元组。
第一个是(名称,权重)元组的列表。
In [1]: data = [("Michael", 275), ("Tom", 150), ("Abe", 200)]
此列表中的顺序无关紧要。 只需在append
组到达时append
到此列表中即可。
现在, 简单的方法是制作浅表副本(引用相同的元组),并在打印它们之前对其进行适当地排序。
In [2]: namelist = [d for d in data]
In [3]: namelist.sort(key=lambda x: x[0])
In [4]: namelist
Out[4]: [('Abe', 200), ('Michael', 275), ('Tom', 150)]
和
In [5]: weightlist = [d for d in data]
In [6]: weightlist.sort(key=lambda x: x[1])
In [7]: weightlist
Out[7]: [('Tom', 150), ('Abe', 200), ('Michael', 275)]
现在,以正确的顺序打印这些内容很简单。
但这在练习中被明确禁止 。 所以您要做的就是这样;
name
, weight
)元组 enumerate
按权重排序的元组列表,并将新元组中的权重与现有元组中的权重进行比较(提示:使用enumerate
以便获得列表中元组的索引)。 一旦找到的权重大于列出的元组的权重,则将新的元组insert
权重排序列表中。 像这样的东西;
In [10]: newvalue = ("Eric", 225)
In [11]: for index, (name, weight) in enumerate(weightlist):
....: if newvalue[1] < weight:
....: weightlist.insert(index, newvalue)
....: break
....:
In [12]: weightlist
Out[12]: [('Tom', 150), ('Abe', 200), ('Eric', 225), ('Michael', 275)]
请注意,这个算法假定weightlist
已经是排序顺序!
另一个与任务相符的解决方案是为每个人使用一个词典。
In [37]: newvalue = {"name": "Eric", "weight": 225, "nextname": None, "nextweight": None}
您还将需要data
列表来保存所有词典。 并且您将需要两个变量startname
和startweight
分别保存名字和最低权重。
创建newvalue
,首先将newvalue["weight"]
与startweight["weight"]
。 如果新权重小于起始权重,则newvalue
变为新的startweight
,并且startweight
newvalue["nextweight"]
设置为旧的起始权重。 如果不是,则移至列表中的下一项并再次进行比较。 请注意,如果要插入链中,则必须更改两个 nextweight
属性!
这是一个双重单链接列表。 以startweight
和startname
开头,您可以通过走动两条链来依次打印两者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.