Bird
Raised Fist0
DSA Pythonprogramming~10 mins

Creating a Singly Linked List from Scratch in DSA Python - Visual Walkthrough

Choose your learning style10 modes available
Concept Flow - Creating a Singly Linked List from Scratch
Start
↓
Create Node with data
↓
Is list empty?
Yes No↓
Set head to new node
↓
Set last node.next to new node
↓
Done
This flow shows how to create a new node and add it to the singly linked list, either as the first node or at the end.
Execution Sample
DSA Python
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            return
        current = self.head
        while current.next:
            current = current.next
        current.next = new_node

ll = LinkedList()
ll.append(1)
ll.append(2)
ll.append(3)
This code creates a singly linked list and appends three nodes with data 1, 2, and 3.
Execution Table
StepOperationNodes in ListPointer ChangesVisual State
1Create new node with data=10Nonenull
2List empty? Yes, set head to new node1head -> Node(1)1 -> null
3Create new node with data=21None1 -> null
4List empty? No, traverse to last node1current -> Node(1)1 -> null
5Set last node.next to new node2Node(1).next -> Node(2)1 -> 2 -> null
6Create new node with data=32None1 -> 2 -> null
7List empty? No, traverse to last node2current -> Node(1)1 -> 2 -> null
8Move current to next node2current -> Node(2)1 -> 2 -> null
9Set last node.next to new node3Node(2).next -> Node(3)1 -> 2 -> 3 -> null
10End of append operations3No pointer changes1 -> 2 -> 3 -> null
💡 All nodes appended; list now has 3 nodes with last node.next = None
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 5After Step 6After Step 9Final
headNoneNoneNode(1)Node(1)Node(1)Node(1)Node(1)Node(1)
currentNoneNoneNoneNode(1)Node(1)NoneNode(2)None
new_nodeNoneNode(1)NoneNode(2)NoneNode(3)NoneNone
list size00112233
Key Moments - 3 Insights
Why do we check if the list is empty before adding a new node?
Because if the list is empty (head is None), we must set head to the new node directly. This is shown in execution_table step 2 where head changes from None to Node(1).
Why do we traverse the list to find the last node before adding a new node?
Because in a singly linked list, we can only add a new node at the end by finding the last node whose next is None. This traversal is shown in steps 4, 7, and 8.
What does the 'next' pointer of the last node point to after appending?
It points to the new node added. For example, in step 5, Node(1).next points to Node(2), and in step 9, Node(2).next points to Node(3).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the visual state after step 5?
A2 -> 1 -> null
B1 -> null
C1 -> 2 -> null
Dnull
💡 Hint
Check the 'Visual State' column in row for step 5.
At which step does the head pointer first get assigned a node?
AStep 1
BStep 2
CStep 4
DStep 5
💡 Hint
Look at the 'Pointer Changes' column to see when head changes from None.
If we skip the traversal loop, what would happen when appending the second node?
AThe new node would be added after the last node correctly
BThe new node would become head, losing the first node
CThe list would remain unchanged
DAn error would occur
💡 Hint
For the second node, current is set to head (which is the last node), and since head.next is None, the loop doesn't run anyway, so skipping it adds correctly.
Concept Snapshot
Creating a singly linked list:
- Define Node with data and next pointer
- Start with head = None
- To append: create new node
- If list empty, set head to new node
- Else traverse to last node
- Set last node.next to new node
- List ends with last node.next = None
Full Transcript
We start by creating a Node class with data and next pointer. The LinkedList class has a head pointer initially None. When appending, we create a new node. If the list is empty, we set head to this new node. Otherwise, we traverse from head to find the last node (where next is None). Then we set last node's next pointer to the new node. This process is repeated for each append. The execution table shows each step, pointer changes, and the visual linked list state. The variable tracker shows how head, current, new_node, and list size change over time. Key moments clarify why we check if the list is empty and why traversal is needed. The visual quiz tests understanding of these steps. The concept snapshot summarizes the process in simple steps.

Practice

(1/5)
1. What is the main purpose of a Singly Linked List in data structures?
easy
A. To store elements with keys and values for fast lookup
B. To store elements in a sequence where each element points to the next
C. To store elements in a sorted array for binary search
D. To store elements in a tree structure with parent and child nodes

Solution

  1. Step 1: Understand the structure of a singly linked list

    A singly linked list stores elements in nodes where each node points to the next node, forming a chain.
  2. Step 2: Compare with other data structures

    Unlike arrays or trees, singly linked lists do not store keys or have parent-child relationships; they only link sequentially.
  3. Final Answer:

    To store elements in a sequence where each element points to the next -> Option B
  4. Quick Check:

    Singly Linked List = sequence with next pointers [OK]
Hint: Remember: singly linked list nodes point only forward [OK]
Common Mistakes:
  • Confusing linked lists with arrays or hash maps
  • Thinking nodes have backward pointers (that's doubly linked list)
  • Assuming linked lists store key-value pairs
2. Which of the following is the correct way to define a node class for a singly linked list in Python?
easy
A. class Node: def __init__(self, data, next): self.data = data self.next = next self.prev = None
B. class Node: def __init__(self, data): self.data = data self.prev = None
C. class Node: def __init__(self, data): self.data = data self.next = None
D. class Node: def __init__(self): self.data = None self.next = None self.prev = None

Solution

  1. Step 1: Identify the correct attributes for a singly linked list node

    A singly linked list node stores data and a pointer to the next node only, so it needs data and next.
  2. Step 2: Check the constructor parameters and attributes

    class Node: def __init__(self, data): self.data = data self.next = None correctly initializes data and sets next to None by default. Other options include prev which is for doubly linked lists or incorrect parameters.
  3. Final Answer:

    class Node: def __init__(self, data): self.data = data self.next = None -> Option C
  4. Quick Check:

    Node has data and next only [OK]
Hint: Singly linked list nodes have no 'prev' pointer [OK]
Common Mistakes:
  • Adding a 'prev' pointer by mistake
  • Not initializing 'next' to None
  • Using extra parameters unnecessarily
3. What will be the output of the following code that creates a singly linked list with nodes 10, 20, 30 and prints the list?
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node

    def print_list(self):
        current = self.head
        while current:
            print(current.data, end=' -> ')
            current = current.next
        print('None')

ll = LinkedList()
ll.append(10)
ll.append(20)
ll.append(30)
ll.print_list()
medium
A. 10 -> 20 -> None
B. 30 -> 20 -> 10 -> None
C. None
D. 10 -> 20 -> 30 -> None

Solution

  1. Step 1: Trace the append method calls

    Appending 10 sets head to node with data 10. Then 20 and 30 are added at the end by traversing the list.
  2. Step 2: Trace the print_list method

    Prints nodes in order: 10, then 20, then 30, each followed by ' -> ', ending with 'None'.
  3. Final Answer:

    10 -> 20 -> 30 -> None -> Option D
  4. Quick Check:

    Append adds at end, print shows order [OK]
Hint: Append adds nodes at list end; print shows order [OK]
Common Mistakes:
  • Assuming append adds at front
  • Printing without 'None' at end
  • Confusing order of nodes
4. The following code tries to append nodes to a singly linked list but does not work as expected. What is the error?
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
        else:
            last = self.head
            while last.next:
                last = last.next
            last = new_node

ll = LinkedList()
ll.append(1)
ll.append(2)
ll.append(3)

current = ll.head
while current:
    print(current.data, end=' -> ')
    current = current.next
print('None')
medium
A. The line 'last = new_node' does not link the new node to the list
B. The head is never initialized
C. The Node class is missing the 'prev' pointer
D. The while loop condition should be 'while last is not None'

Solution

  1. Step 1: Analyze the append method's else block

    The code finds the last node correctly but then does 'last = new_node' which only changes the local variable, not the last node's next pointer.
  2. Step 2: Identify the fix

    To link the new node, it should be 'last.next = new_node' to update the last node's next pointer.
  3. Final Answer:

    The line 'last = new_node' does not link the new node to the list -> Option A
  4. Quick Check:

    Assign to last.next to link nodes [OK]
Hint: Update last.next, not last variable, to link nodes [OK]
Common Mistakes:
  • Assigning new_node to last instead of last.next
  • Not updating the head when list is empty
  • Confusing variable assignment with pointer update
5. You want to create a singly linked list from scratch that supports inserting a new node at the beginning and printing the list. Which code snippet correctly implements this?
hard
A. class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def insert_at_beginning(self, data): new_node = Node(data) new_node.next = self.head self.head = new_node def print_list(self): current = self.head while current: print(current.data, end=' -> ') current = current.next print('None')
B. class Node: def __init__(self, data): self.data = data self.prev = None self.next = None class LinkedList: def __init__(self): self.head = None def insert_at_beginning(self, data): new_node = Node(data) new_node.prev = self.head self.head = new_node def print_list(self): current = self.head while current: print(current.data, end=' -> ') current = current.next print('None')
C. class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def insert_at_beginning(self, data): new_node = Node(data) self.head = new_node def print_list(self): current = self.head while current: print(current.data, end=' -> ') current = current.next print('None')
D. class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def insert_at_beginning(self, data): new_node = Node(data) new_node.next = None self.head = new_node def print_list(self): current = self.head while current: print(current.data, end=' -> ') current = current.next print('None')

Solution

  1. Step 1: Understand insert at beginning logic

    To insert at the beginning, new node's next should point to current head, then head updated to new node.
  2. Step 2: Check each option's insert_at_beginning method

    class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def insert_at_beginning(self, data): new_node = Node(data) new_node.next = self.head self.head = new_node def print_list(self): current = self.head while current: print(current.data, end=' -> ') current = current.next print('None') correctly sets new_node.next = self.head and updates head. class Node: def __init__(self, data): self.data = data self.prev = None self.next = None class LinkedList: def __init__(self): self.head = None def insert_at_beginning(self, data): new_node = Node(data) new_node.prev = self.head self.head = new_node def print_list(self): current = self.head while current: print(current.data, end=' -> ') current = current.next print('None') wrongly uses prev pointer. class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def insert_at_beginning(self, data): new_node = Node(data) self.head = new_node def print_list(self): current = self.head while current: print(current.data, end=' -> ') current = current.next print('None') misses linking new_node.next. class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def insert_at_beginning(self, data): new_node = Node(data) new_node.next = None self.head = new_node def print_list(self): current = self.head while current: print(current.data, end=' -> ') current = current.next print('None') sets new_node.next to None, losing old list.
  3. Final Answer:

    Option A code snippet correctly inserts at beginning and prints list -> Option A
  4. Quick Check:

    New node points to old head, then head updated [OK]
Hint: New node's next = old head; update head to new node [OK]
Common Mistakes:
  • Not linking new node to old head
  • Using prev pointer in singly linked list
  • Setting new_node.next to None incorrectly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard