1

Hey guys I'm really lost. I am writing a Doubly Linked List program for my Data Structures class and I just can't figure it out.

UPDATE: So I have my singly linked list assignment done. How can I convert it to a doubly linked list and use the data provided to load it in and print it?

Objective

Program Specification:

  1. Read data for names and weights for 15 people from the console where there is a name on a line followed by a weight on the next line, like in names.txt.

  2. Your program will build a list for the data maintained in ascending order based on both name and weight via a doubly linked list.

  3. This dll will use one pointer to keep weights in sorted order, and use the other link to keep names on sorted order.

  4. You need to build the list as you go maintaining this ordering, so at any time a print method was called it would print the related field in order. (This means nodes are added to the list in sorted order, elements are not added to the list followed by a sort called on the list.)

For example after 3 elements are added for (Name – Weight): Michael – 275, Tom – 150, Abe – 200.

Output: Names & weights sorted(ascending) by name. : Abe – 200, Michael – 275, Tom - 150 Names & weights sorted(ascending) by weight. : Tom – 150, Abe – 200, Michael - 275

Small piece of code I'm going from

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)

My singly Linked list (sorted) program

#!/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

Data: 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

As you can see I haven't done much. I am not sure how to load the data in properly and I'm just overall lost. I'm not sure where to start. I've looked at a couple examples online but they are just cryptic to me.

Thank you for any help in advance. I greatly appreciate it.

7
  • 12
    What an awful assignment for a Python class. Or, what an awful choice of language for a data structures class. What school is this from? Commented Nov 6, 2013 at 4:11
  • 6
    -1 for uploading (almost) entire homework here. Should ask specific questions .e.g., what can be done to perform a certain task using a certain language/technology. Commented Nov 6, 2013 at 4:11
  • next should probably be another instance of LinkedList rather than a string ... same with prev ... and yes this is not a great example for a python program... it is more suited to c/c++ but meh Commented Nov 6, 2013 at 4:12
  • 3
    Whatever school out there is teaching people to use __slots__ unnecessarily needs remedial instruction in the Zen. Commented Nov 6, 2013 at 4:14
  • Sorry guys this is just what I could come up with. I chose to use python for this Data Structures class since I know it better then C==. Let me get back to you with more specifics and better code for this assignment. Commented Nov 6, 2013 at 4:26

2 Answers 2

2

Given the fact that the problem definition specifies "pointers", python is not a suitable language to implement this. But you can use python variables as "pointers" (or rather references) because that is what they are; A python variable is just a name for or refrence to an object.

But if you want to implement in python, I would use a list ot tuples.

The first one is a list of (name, weight) tuples.

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

The order in this list doesn't matter. Just append new tuples to this list as they arrive.

Now the easy way to do it would be to make shallow copies (which reference the same tuples), and sort them appropriately just before you print them;

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

and

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

Printing these in the correct sequence is now trivial.

But this is expressly forbidden in the exercise. So what you have to do is something like this;

  • Create a new (name, weight) tuple
  • Walk the list of tuples sorted by weight and compare the weight in the new tuple with the weight in the existing tuple (hint: use enumerate so you get the index of the tuple in the list). As soon as you've found a weight that is greater than the weight of the listed tuple, insert the new tuple in the weight-sorted list.
  • similar for the name-sorted list, but then using the name as the compare value.

Something like this;

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

Note that this algorithm assumes that weightlist is already in sorted order!


Another solution that is more in line of the assignment would be to use a dictionary for every person;

In [37]: newvalue = {"name": "Eric", "weight": 225, "nextname": None, "nextweight": None}

You will also need the data list to hold all the dictionaries. And you will need two variables startname and startweight to hold the first name and lowest weight respectively.

After you have made a newvalue, you start with comparing newvalue["weight"] to startweight["weight"]. If the new weight is smaller than the startweight, then newvalue becomes the new startweight, and newvalue["nextweight"] should be set to the old startweight. If not, you move to the next item in the list and compare again. Note that if you want to insert in the chain, you have to change two nextweight attributes!

This is a double, singly linked list. Beginning with startweight and startname you can print both in order by walking both chains.

Sign up to request clarification or add additional context in comments.

Comments

1

Here is how I would do it. I suggest that you create a new question or search around for how to read data from a text file.

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

And some results:

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 Comment

oh boy, i didn't see the date this was asked. i have a feeling this class is already over

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.