Calvin Ellington
Calvin Ellington

Reputation: 723

Incorrectly returning the value of a Node at position 'm' in a linked list

I have a homework problem:

Find the element in a singly linked list that's m elements from the end. For example, if a linked list has 5 elements, the 3rd element from the end is the 3rd element. The function definition should look like question5(ll, m), where ll is the first node of a linked list and m is the "mth number from the end". You should copy/paste the Node class below to use as a representation of a node in the linked list. Return the value of the node at that position.

The code to paste is the 4-line definition of class Node. My attempt follows.

class Node(object):
  def __init__(self, data):
    self.data = data
    self.next = None

ll = None

# Provided Node Class.
class Node(object):
    def __init__(self, data):
        self.data = data
        self.next = None

# Function for adding values to list.
def add(new_data):
    global ll
    node = Node(new_data)
    node.next = ll
    ll = node

def Question5(ll, m):
    # Start of list.
    element = ll
    # Node count.
    c = 0
    # Set end of list to False.
    endlist = False
    # Loop until the linked list reaches its end.
    while not endlist:
        c += 1
        element = element.next
        if element.next == None:
            endlist = True

    # Set node value as count - position m
    position = c - m
    # If position is less than 0, end has been reached
    if(m < 0):
        return "8, End of list"
    # If not the end of list return value at position m
    else:
        return position

global ll
add(1)
add(2)
add(3)
add(4)
add(5)
add(6)
add(7)
add(8)
print ("Value of node at position m from the end is: ", Question5(ll, -1))
#('Value of node at position m from the end is: ', '8, End of list')
print ("Value of node at position m from the end is: ", Question5(ll, 3))
#('Value of node at position m from the end is: ', 4)
print ("Value of node at position m from the end is: ", Question5(ll, 2))
#('Value of node at position m from the end is: ', 5)
print ("Value of node at position m from the end is: ", Question5(ll, 0))
#('Value of node at position m from the end is: ', 7)

My reviewer says that my solution is incorrect, as I am not returning the actual value of the node at position 'm'. What would be the correct way to return the value of a node object in this scenario?


Edit: for the sake of finalizing this question I have included the solution I was able to implement as per the advice in the second answer below

New code:

ll = None

# Provided Node Class.
class Node(object):
    def __init__(self, data):
        self.data = data
        self.next = None

# Function for adding values to list.
def add(new_data):
    global ll
    node = Node(new_data)
    node.next = ll
    ll = node

def Question5(ll, m):
    # Nodes already traversed
    element1 = ll
    # Nodes from beginning
    element2 = ll
    # Node count.
    c = 0

    # Traverse list until c = m
    if(ll is not None):
        while(c < m):
            element2 = element2.next
            c += 1

    # Loop until the linked list reaches its end.
    while(element2 is not None):
        #print ("This is element 1:", element1.data)
        #print ("This is element 2:", element2.data)
        element1 = element1.next
        element2 = element2.next

    # return the current node at m steps from the end
    return element1.data

global ll
# List meant to represent a telephone with 0 being the end.
add("0")
add("9 WXYZ")
add("8 TUV")
add("7 PQRS")
add("6 MNO")
add("5 JKL")
add("4 GHI")
add("3 DEF")
add("2 ABC")
add("1")
# Singly Linked List:
# 1 - 2 ABC - 3 DEF - 4 GHI - 5 JKL - 6 MNO - 7 PQRS - 8 TUV - 9 WXYZ - 0
print ("node at position m in relation to the end of ll is: ", Question5(ll, 4))
# ('node at position m in relation to the end of ll is: ', '7 PQRS')
print ("node at position m in relation to the end of ll is: ", Question5(ll, 8))
# ('node at position m in relation to the end of ll is: ', '3 DEF')
print ("node at position m in relation to the end of ll is: ", Question5(ll, 1))
# ('node at position m in relation to the end of ll is: ', '0')
print """---End Question 5---

Upvotes: 0

Views: 168

Answers (1)

Prune
Prune

Reputation: 77860

Look at your output: when m is 2, your code returns 5. The problem statement clearly shows that it expects 7, the second element counting form the end of the list. Your code backs off two extra elements: apparently, the only way you allow returning 8 is to give a position of -1, and 0 is required to get a value of 7.

Fix your counting, and you'll be fine; you're already handling the traversal correctly.


Now that I've had time to look over the code, I'm going to back off from my previous answer somewhat: you do get to the end of the list properly, but that's about all your code does correctly. To look at this from a functional standpoint, your reviewer is entirely correct: you don't return the node's value at all. You compute a position and assume that the node's value matches. You're not allowed to do that.

Consider a list built this way, on phone buttons:

add("ABC")
add("DEF")
add("GHI")
add("JKL")
add("MNO")
add("PRS")
add("TUV")
add("WXY")
add("QZ")

If the input is 2, you have to return "WXY". I just tried this with your Question5 code, and it still returns numbers. Wrong.

You have to find your way to the end of the list, and then find the proper value from the end of the list. There are various ways to do this. For instance, build a list of node values as you traverse the list; then just print the value from position -m in that list. Another possibility is to use recursion to find the end of the list, then return a counter back up the recursion chain to figure out which instance should print the value of the current node.

Can you take the next steps on your own.

Upvotes: 1

Related Questions