0

I'm trying to create a function that takes in a head of a linked list and a value, create a node with that value, set node.next to head, and then update the the new node to be the head. I got it to work but I feel like I'm doing this very inefficiently by returning values, so I was wondering if there is a more elegant way to do this.

Here's the code I'm using:

#!/usr/bin/env python3
"""
This module is a linked list implementation.
"""

class Node:
    """
    Node structure to be used in our linked list.
    """
    def __init__(self, value):
        self.value = value
        self.next = None

def linked_insert(head, value):
    """
    Insert new node to the tail of the linked list.
    Time Complexity: O(n)
    """
    current = head
    while current.next is not None:
        current = current.next
    current.next = Node(value)

def linked_insert2(head, value):
    """
    Insert new node to the head of the linked list, making sure to update head.
    Time Complexity: O(1)
    """
    to_insert = Node(value)
    to_insert.next = head
    head = to_insert
    return head


def linked_extract(head):
    """
    Extract the last element in the linked list
    """
    current = head

    while current.next.next is not None:
        current = current.next

    tail = current.next
    current.next = None

    return tail


def linked_display(head):
    """
    Print all node values in the linked list
    """
    current = head
    while current is not None:
        print(current.value)
        current = current.next


# Test Program
head = Node(5)
# linked_insert(head, 1)
# linked_insert(head, 2)
# linked_insert(head, 3)
#
# print(linked_extract(head).value)

head = linked_insert2(head, 1)
head = linked_insert2(head, 2)
head = linked_insert2(head, 3)
linked_display(head)

Is there a way to do this without having to return the value of head and setting head = returned value in the test program?

The function in question is linked_insert2(). The whole program is meant to be a linked list implementation in python.

Implementation using linked list class:

#!/usr/bin/env python3

"""
This module is a linked list implementation.
"""

class Node:
    """
    Node class to be used in our linked list.
    """
    def __init__(self, value):
        self.value = value
        self.next = None


class Linkedlist:
    """
    Linked list implementation that supports functions including inserting
    at head, inserting at tail, extracting elements, and displaying all
    elements in the ist
    """
    def __init__(self, head):
        self.head = Node(head)

    def insert(self, value):
        """
        Insert new node to the tail of the linked list.
        Time Complexity: O(n)
        """
        current = self.head
        while current.next is not None:
            current = current.next
        current.next = Node(value)

    def insert2(self, value):
        """
        Insert new node to the head of the linked list, making sure to update head.
        Time Complexity: O(1)
        """
        to_insert = Node(value)
        to_insert.next = self.head
        self.head = to_insert


    def extract(self):
        """
        Extract the last element in the linked list
        """
        current = self.head

        while current.next.next is not None:
            current = current.next

        tail = current.next
        current.next = None

        return tail


    def display(self):
        """
        Print all node values in the linked list
        """
        current = self.head
        while current is not None:
            print(current.value)
            current = current.next


# Test Program
head = Linkedlist(5)
# linked_insert(head, 1)
# linked_insert(head, 2)
# linked_insert(head, 3)

head.insert2(1)
head.insert2(2)
head.insert2(3)
head.display()
YSA
  • 799
  • 1
  • 12
  • 30
  • In the comment you are asked to make sure you update head. why don't you want to do that? – Saher Ahwal Feb 24 '17 at 22:10
  • 1
    You could have a _linked list_ object with those functions as it's methods. This way you wouldn't have to keep the head as you insert. But also, why bother, this seems good enough. – bosnjak Feb 24 '17 at 22:11
  • @SaherAhwal I think I'm doing that when I set `head = to_insert` in the end? – YSA Feb 24 '17 at 22:17
  • @bosnjak I am just curious as to how to implement O(1) insertion elegantly without having to set head equal to the return value every time. – YSA Feb 24 '17 at 22:18
  • 1
    @YSA afaik this insertion is O(1), there is nothing wrong with keeping a reference to head. – bosnjak Feb 24 '17 at 22:20
  • @bosnjak true, I'm question the cleanliness of the code at this point. If I were to implement it in C, I would switching the pointers around and wouldn't need to return the value, so I was wondering how to do the same thing in python just to solidify my understanding of the language. – YSA Feb 24 '17 at 22:23
  • 1
    @YSA: I'm not sure how you would do it in C without keeping the pointer to the head? You would need to do the same. – bosnjak Feb 24 '17 at 22:26
  • @bosnjak: `void linked_insert(node *head, int value) { new_node = make_node(value); value->next = head; head = new_node; }` Assume make_node is a function that mallocs space for struct node and set next to NULL. I think that conveys what I'm trying to do in C. – YSA Feb 24 '17 at 22:31
  • 1
    I see what you mean. It's nothing to worry about, this is perfectly ok in Python. Read this to understand better what's going on: http://stackoverflow.com/a/986145/2842884. Python is much more higher level than C. – bosnjak Feb 24 '17 at 22:37
  • I see, thank you so much for following up. I really appreciate it. – YSA Feb 24 '17 at 22:39
  • @bosnjak actually follow-up questions, why does it work if I have a Linkedlist class? I just tried it and it works – YSA Feb 24 '17 at 22:52
  • 1
    @YSA because it keeps the head reference in the `self`. If you show me your new implementation I can be of more help. – bosnjak Feb 24 '17 at 22:55
  • @bosnjak just updated my question! I guess my question now is why was I not able to rebind the head reference before and now it works fine? – YSA Feb 24 '17 at 22:57
  • 1
    @YSA it works because now you are storing the `head` implicitly from inside the object method with `self.head`. Once you store it there, there is no need to return it or store it again, it is stored in the object itself. – bosnjak Feb 24 '17 at 22:59
  • 1
    @bosnjak aah, I see! Thank you!! – YSA Feb 24 '17 at 23:00
  • @YSA: you're welcome. Good luck! – bosnjak Feb 24 '17 at 23:02

0 Answers0