Bird
Raised Fist0
DSA Goprogramming

Creating a Singly Linked List from Scratch in DSA Go - Step-by-Step

Choose your learning style10 modes available
Mental Model
A singly linked list is a chain of boxes where each box holds a value and points to the next box in line.
Analogy: Imagine a treasure hunt where each clue leads you to the next clue. Each clue is like a box holding a value and a pointer to the next clue.
head -> [value | next] -> [value | next] -> [value | next] -> null
Dry Run Walkthrough
Input: Create a singly linked list with values 1, 2, and 3 in that order.
Goal: Build the linked list so it holds 1 -> 2 -> 3 -> null
Step 1: Create the first node with value 1 and set it as head
head -> [1 | null]
Why: We need a starting point for the list
Step 2: Create the second node with value 2 and link it to the first node
head -> [1 | next->2] -> [2 | null]
Why: Link the new node after the first to extend the list
Step 3: Create the third node with value 3 and link it to the second node
head -> [1 | next->2] -> [2 | next->3] -> [3 | null]
Why: Add the last node to complete the list
Result:
head -> [1 | next->2] -> [2 | next->3] -> [3 | null]
Annotated Code
DSA Go
package main

import "fmt"

// Node represents one element in the linked list
type Node struct {
	value int
	next  *Node
}

// LinkedList holds the head of the list
type LinkedList struct {
	head *Node
}

// Append adds a new node with given value at the end
func (ll *LinkedList) Append(val int) {
	newNode := &Node{value: val, next: nil} // create new node
	if ll.head == nil {
		ll.head = newNode // if list empty, new node is head
		return
	}
	current := ll.head
	for current.next != nil {
		current = current.next // move to last node
	}
	current.next = newNode // link last node to new node
}

// PrintList prints all values in the list
func (ll *LinkedList) PrintList() {
	current := ll.head
	for current != nil {
		fmt.Printf("%d -> ", current.value) // print current value
		current = current.next // move to next node
	}
	fmt.Println("null")
}

func main() {
	ll := LinkedList{}
	ll.Append(1) // step 1
	ll.Append(2) // step 2
	ll.Append(3) // step 3
	ll.PrintList() // print final list
}
newNode := &Node{value: val, next: nil} // create new node
create a new node with the given value and no next node
if ll.head == nil { ll.head = newNode return }
if list is empty, set new node as head and stop
current := ll.head for current.next != nil { current = current.next }
traverse list to find last node
current.next = newNode
link last node to new node to extend list
current := ll.head for current != nil { fmt.Printf("%d -> ", current.value) current = current.next }
traverse list and print each node's value
OutputSuccess
1 -> 2 -> 3 -> null
Complexity Analysis
Time: O(n) because appending requires traversing all nodes to find the end
Space: O(n) because each new value creates a new node stored in memory
vs Alternative: Compared to arrays, linked lists allow easy insertion without shifting elements but require traversal to append
Edge Cases
Empty list when appending first node
The new node becomes the head of the list
DSA Go
if ll.head == nil {
	ll.head = newNode
	return
}
When to Use This Pattern
When you need a flexible list that grows by linking nodes one after another, use a singly linked list to avoid shifting elements.
Common Mistakes
Mistake: Not setting the head when the list is empty
Fix: Check if head is nil and assign the new node as head before traversing
Summary
Creates a chain of nodes where each node points to the next, forming a singly linked list.
Use it when you want a list that can grow dynamically without moving existing elements.
Remember the head points to the first node, and each node points to the next until null ends the list.

Practice

(1/5)
1. What is the main purpose of a singly linked list in data structures?
easy
A. To store elements in a hash table for fast lookup
B. To store elements in a tree-like structure with multiple branches
C. To store elements in a fixed-size array for quick access
D. To store elements in a linear order where each element points to the next

Solution

  1. Step 1: Understand singly linked list structure

    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 trees or arrays, singly linked lists have a linear sequence with pointers only to the next element.
  3. Final Answer:

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

    Singly linked list = linear chain with next pointers [OK]
Hint: Remember: singly linked list nodes point only forward [OK]
Common Mistakes:
  • Confusing singly linked list with trees or arrays
  • Thinking nodes have pointers to previous nodes
  • Assuming fixed size storage like arrays
2. Which of the following is the correct way to define a node struct for a singly linked list in Go?
easy
A. type Node struct { value int; next *Node }
B. type Node struct { value int; prev *Node }
C. type Node struct { value int; next Node }
D. type Node struct { value int; next interface{} }

Solution

  1. Step 1: Identify correct pointer usage

    In Go, the next node must be a pointer to Node, so *Node is correct.
  2. Step 2: Check struct fields

    Field 'value' stores data, 'next' points to the next node. 'prev' is for doubly linked lists, and 'interface{}' is too generic.
  3. Final Answer:

    type Node struct { value int; next *Node } -> Option A
  4. Quick Check:

    Node next pointer = *Node [OK]
Hint: Use *Node for next pointer in Go struct [OK]
Common Mistakes:
  • Using value type instead of pointer for next
  • Confusing singly linked list with doubly linked list (prev pointer)
  • Using interface{} instead of *Node for next
3. What will be the output of the following Go code that creates a singly linked list with nodes 1 -> 2 -> 3?
package main
import "fmt"
type Node struct {
  value int
  next  *Node
}
func main() {
  head := &Node{value: 1}
  second := &Node{value: 2}
  third := &Node{value: 3}
  head.next = second
  second.next = third
  current := head
  for current != nil {
    fmt.Print(current.value)
    if current.next != nil {
      fmt.Print(" -> ")
    }
    current = current.next
  }
  fmt.Println(" -> null")
}
medium
A. 1 -> 2 -> null
B. 3 -> 2 -> 1 -> null
C. 1 -> 2 -> 3 -> null
D. Compilation error

Solution

  1. Step 1: Trace node creation and linking

    Nodes with values 1, 2, 3 are created and linked in order: head.next = second, second.next = third.
  2. Step 2: Trace printing loop

    Loop prints current.value, then ' -> ' if next exists, moving from head to third, then prints ' -> null'.
  3. Final Answer:

    1 -> 2 -> 3 -> null -> Option C
  4. Quick Check:

    Print nodes in order 1,2,3 with arrows [OK]
Hint: Follow next pointers from head to end [OK]
Common Mistakes:
  • Printing nodes in reverse order
  • Missing last node in output
  • Confusing pointer assignments causing nil errors
4. Identify the error in this Go code snippet that tries to append a new node with value 4 to the end of a singly linked list:
func appendNode(head *Node, val int) {
  newNode := &Node{value: val}
  current := head
  for current.next != nil {
    current = current.next
  }
  current = newNode
}
medium
A. The loop condition should be current != nil instead of current.next != nil
B. The new node is not linked to the list; current pointer is reassigned incorrectly
C. The new node should be created with next pointing to head
D. The function should return the new head pointer

Solution

  1. Step 1: Analyze the loop and pointer update

    The loop correctly finds the last node where current.next is nil.
  2. Step 2: Check how new node is linked

    Assigning current = newNode only changes the local variable, not the last node's next pointer. It should be current.next = newNode.
  3. Final Answer:

    The new node is not linked to the list; current pointer is reassigned incorrectly -> Option B
  4. Quick Check:

    Link new node by current.next = newNode [OK]
Hint: Assign new node to current.next, not current [OK]
Common Mistakes:
  • Reassigning current instead of current.next
  • Wrong loop condition causing nil pointer dereference
  • Not returning updated head when needed
5. You want to create a function in Go that reverses a singly linked list. Which approach correctly reverses the list by changing the next pointers?
func reverseList(head *Node) *Node {
  var prev *Node = nil
  current := head
  for current != nil {
    nextTemp := current.next
    current.next = prev
    prev = current
    current = nextTemp
  }
  return prev
}
What will be the output if the original list is 1 -> 2 -> 3 -> null and you print the reversed list?
hard
A. 3 -> 2 -> 1 -> null
B. 1 -> 2 -> 3 -> null
C. null
D. Runtime error due to nil pointer

Solution

  1. Step 1: Understand reversal logic

    The function iterates through the list, reversing each node's next pointer to point to the previous node.
  2. Step 2: Trace reversal on list 1 -> 2 -> 3

    After reversal, the list becomes 3 -> 2 -> 1 -> null, and prev points to new head.
  3. Final Answer:

    3 -> 2 -> 1 -> null -> Option A
  4. Quick Check:

    Reversed list head = prev = 3 [OK]
Hint: Reverse pointers by tracking prev, current, next [OK]
Common Mistakes:
  • Not updating current.next correctly
  • Losing track of next node causing infinite loop
  • Returning old head instead of new head
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