Python中的双链表

时间:2013-11-06 04:06:52

标签: python data-structures python-3.x linked-list

嘿伙计们,我真的输了。我正在为我的Data Structures类编写一个Doubly Linked List程序,我无法理解它。

更新:所以我完成了单链表的分配。如何将其转换为双向链表并使用提供的数据加载并打印出来?

目的

  

计划规范:

     
      
  1. 从控制台读取15个人的姓名和体重数据,其中有一个名字在一行,后面是下一行的重量,   比如names.txt。

  2.   
  3. 您的程序将根据名称和重量通过双向链表建立一个按升序维护的数据列表。

  4.   
  5. 此dll将使用一个指针按重排顺序保持权重,并使用另一个链接将名称保持在排序顺序。

  6.   
  7. 您需要在维护此排序时构建列表,因此在任何时候调用print方法都会打印相关字段   为了。 (这意味着节点按排序顺序添加到列表中,   元素不会添加到列表中,后跟调用的排序   列表)。

  8.         

    例如,为(名称 - 重量)添加3个元素后:迈克尔 -   275,Tom - 150,Abe - 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

数据:Names.txt

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

你可以看到我做得不多。我不确定如何正确加载数据,我只是整体丢失。我不知道从哪里开始。我在网上看了几个例子,但它们对我来说只是神秘莫测。

提前感谢您的帮助。我非常感激。

2 个答案:

答案 0 :(得分:1)

我将如何做到这一点。我建议您创建一个新问题或搜索如何从文本文件中读取数据。

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

答案 1 :(得分:1)

鉴于问题定义指定&#34;指针&#34;,python不是实现它的合适语言。但你可以使用python变量作为&#34;指针&#34; (或者更确切地说引用)因为它们就是这样; python变量只是对象的名称或参考。

但是如果你想在python中实现,我会使用一个列表ot元组。

第一个是(名称,权重)元组列表。

In [1]: data = [("Michael", 275), ("Tom", 150), ("Abe", 200)]

此列表中的顺序并不重要。当这些列表到达时,只需append个新元组。

现在 easy 的方法是制作浅拷贝(引用相同的元组),并在打印之前对它们进行适当的排序;

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)]

以正确的顺序打印这些内容现在变得微不足道了。

但这是明确禁止在练习中。所以你要做的就是这样;

  • 创建新的(nameweight)元组
  • 遍历按权重排序的元组列表,并将新元组中的权重与现有元组中的权重进行比较(提示:使用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列表来容纳所有词典。 您需要两个变量startnamestartweight来分别保留名字和最低权重。

制作newvalue后,首先要将newvalue["weight"]startweight["weight"]进行比较。如果新权重小于起始权重,则newvalue将成为新的startweightnewvalue["nextweight"]应设置为旧的起始权重。如果没有,您将移动到列表中的下一个项目并再次进行比较。请注意,如果要在链中插入,则必须更改两个 nextweight属性!

这是一个双重的单链表。从startweightstartname开始,您可以通过走两条链来按顺序打印。