Bird
Raised Fist0
DSA Goprogramming

Insert at Specific Position in Doubly Linked List in DSA Go

Choose your learning style10 modes available
Mental Model
We add a new item exactly where we want by changing the links before and after that spot.
Analogy: Imagine a train with cars linked front and back. To add a new car in the middle, you disconnect the two cars at that spot and connect the new car between them.
null ← 1 ↔ 2 ↔ 3 -> null
          ↑
       position 2
Dry Run Walkthrough
Input: list: 1 ↔ 2 ↔ 3, insert value 4 at position 2
Goal: Insert the value 4 between nodes 1 and 2, so the list becomes 1 ↔ 4 ↔ 2 ↔ 3
Step 1: Create new node with value 4
null ← 1 ↔ 2 ↔ 3 -> null, newNode=4
Why: We need a new node to insert
Step 2: Traverse to node at position 1 (node with value 1)
null ← 1[↑curr] ↔ 2 ↔ 3 -> null, newNode=4
Why: We want to insert after node 1
Step 3: Set newNode.prev to curr (node 1)
null ← 1[↑curr] ↔ 2 ↔ 3 -> null, newNode=4 (prev->1)
Why: Link new node back to node 1
Step 4: Set newNode.next to curr.next (node 2)
null ← 1[↑curr] ↔ 2 ↔ 3 -> null, newNode=4 (prev->1, next->2)
Why: Link new node forward to node 2
Step 5: Set curr.next.prev to newNode (node 2.prev -> 4)
null ← 1[↑curr] ↔ 4 ↔ 2 ↔ 3 -> null
Why: Link node 2 back to new node
Step 6: Set curr.next to newNode (node 1.next -> 4)
null ← 1 ↔ 4 ↔ 2 ↔ 3 -> null
Why: Link node 1 forward to new node
Result:
null ← 1 ↔ 4 ↔ 2 ↔ 3 -> null
Annotated Code
DSA Go
package main

import "fmt"

type Node struct {
	val  int
	next *Node
	prev *Node
}

type DoublyLinkedList struct {
	head *Node
}

func (dll *DoublyLinkedList) InsertAtPosition(pos int, val int) {
	newNode := &Node{val: val}
	if pos == 1 {
		// Insert at head
		newNode.next = dll.head
		if dll.head != nil {
			dll.head.prev = newNode
		}
		dll.head = newNode
		return
	}
	curr := dll.head
	count := 1
	// Traverse to node before position
	for curr != nil && count < pos-1 {
		curr = curr.next
		count++
	}
	if curr == nil {
		// Position is beyond list length, ignore insertion
		return
	}
	newNode.prev = curr
	newNode.next = curr.next
	if curr.next != nil {
		curr.next.prev = newNode
	}
	curr.next = newNode
}

func (dll *DoublyLinkedList) PrintList() {
	curr := dll.head
	for curr != nil {
		fmt.Printf("%d", curr.val)
		if curr.next != nil {
			fmt.Printf(" ↔ ")
		}
		curr = curr.next
	}
	fmt.Println()
}

func main() {
	dll := &DoublyLinkedList{}
	dll.head = &Node{val: 1}
	dll.head.next = &Node{val: 2, prev: dll.head}
	dll.head.next.next = &Node{val: 3, prev: dll.head.next}

	// Insert 4 at position 2
	dll.InsertAtPosition(2, 4)
	dll.PrintList()
}
newNode := &Node{val: val}
Create new node with given value
if pos == 1 { ... }
Handle insertion at head separately
curr := dll.head count := 1 for curr != nil && count < pos-1 { curr = curr.next count++ }
Traverse to node before insertion position
newNode.prev = curr newNode.next = curr.next
Link new node to previous and next nodes
if curr.next != nil { curr.next.prev = newNode }
Link next node back to new node if it exists
curr.next = newNode
Link previous node forward to new node
OutputSuccess
1 ↔ 4 ↔ 2 ↔ 3
Complexity Analysis
Time: O(n) because we may need to traverse up to n nodes to reach the insertion position
Space: O(1) because we only create one new node and use a few pointers
vs Alternative: Compared to inserting at head or tail which is O(1), inserting at a specific position requires traversal, making it O(n)
Edge Cases
Insert at position 1 (head insertion)
New node becomes the new head, links updated accordingly
DSA Go
if pos == 1 { ... }
Insert at position beyond list length
Insertion is ignored (no change to list)
DSA Go
if curr == nil { return }
Insert into empty list at position 1
New node becomes head
DSA Go
if pos == 1 { ... }
When to Use This Pattern
When you need to add an element exactly at a certain place in a doubly linked list, use this insertion pattern to adjust both forward and backward links carefully.
Common Mistakes
Mistake: Forgetting to update the prev pointer of the node after the insertion point
Fix: Always set curr.next.prev = newNode if curr.next is not nil
Mistake: Not handling insertion at head separately
Fix: Add a special case for position 1 to update head pointer and prev links
Summary
Inserts a new node at a given position in a doubly linked list by adjusting next and prev pointers.
Use when you want to add an element anywhere in the list, not just at the ends.
The key is to link the new node both backward and forward to maintain the double links.

Practice

(1/5)
1. What does inserting a node at a specific position in a doubly linked list involve?
easy
A. Only changing the head pointer of the list
B. Adjusting the previous and next pointers of neighboring nodes to include the new node
C. Replacing the node at that position without changing pointers
D. Appending the node at the end regardless of position

Solution

  1. Step 1: Understand doubly linked list structure

    Each node has pointers to both previous and next nodes, so insertion requires updating these pointers.
  2. Step 2: Insert node at specific position

    To insert, update the previous node's next pointer and the next node's previous pointer to point to the new node.
  3. Final Answer:

    Adjusting the previous and next pointers of neighboring nodes to include the new node -> Option B
  4. Quick Check:

    Pointer updates = A [OK]
Hint: Remember both previous and next pointers must be updated [OK]
Common Mistakes:
  • Only updating one pointer and ignoring the other
  • Not handling edge cases like insertion at head or tail
  • Replacing node data instead of inserting new node
2. Which of the following Go code snippets correctly declares a doubly linked list node struct for insertion?
easy
A. type Node struct { data int; prev *Node; next *Node }
B. type Node struct { data int; next *Node }
C. type Node struct { data int; prev int; next int }
D. type Node struct { data int; prev Node; next Node }

Solution

  1. Step 1: Check struct fields for doubly linked list

    A doubly linked list node must have pointers to previous and next nodes, both of type *Node.
  2. Step 2: Validate Go syntax

    type Node struct { data int; prev *Node; next *Node } correctly uses pointers (*Node) for prev and next fields, matching doubly linked list requirements.
  3. Final Answer:

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

    Pointers for prev and next = A [OK]
Hint: Use *Node type for prev and next pointers in struct [OK]
Common Mistakes:
  • Using non-pointer types for prev and next
  • Omitting prev pointer for doubly linked list
  • Using incorrect field types like int for pointers
3. What will be the output of the doubly linked list after inserting a node with value 25 at position 3 in the list 10 <-> 20 <-> 30 <-> 40?
medium
A. 10 <-> 20 <-> 25 <-> 30 <-> 40
B. 10 <-> 25 <-> 20 <-> 30 <-> 40
C. 25 <-> 10 <-> 20 <-> 30 <-> 40
D. 10 <-> 20 <-> 30 <-> 40 <-> 25

Solution

  1. Step 1: Identify position 3 in the list

    Positions: 1=10, 2=20, 3=30, 4=40. Inserting at position 3 means before node with value 30.
  2. Step 2: Insert node with value 25 at position 3

    New node 25 goes between 20 and 30, updating pointers accordingly.
  3. Final Answer:

    10 <-> 20 <-> 25 <-> 30 <-> 40 -> Option A
  4. Quick Check:

    Insert before 3rd node = D [OK]
Hint: Insert before node currently at that position [OK]
Common Mistakes:
  • Inserting after the node at position instead of before
  • Appending at end instead of correct position
  • Confusing position indexing starting at 0
4. Given the following Go code snippet for insertion, what is the error?
func InsertAtPosition(head *Node, data int, pos int) *Node {
    newNode := &Node{data: data}
    if pos == 1 {
        newNode.next = head
        head.prev = newNode
        head = newNode
        return head
    }
    temp := head
    for i := 1; i < pos-1; i++ {
        temp = temp.next
    }
    newNode.next = temp.next
    temp.next.prev = newNode
    temp.next = newNode
    newNode.prev = temp
    return head
}
medium
A. Incorrect assignment of newNode.prev
B. Missing creation of newNode
C. No check if temp or temp.next is nil before accessing pointers
D. Returning newNode instead of head

Solution

  1. Step 1: Analyze pointer usage in loop and insertion

    The loop moves temp to position before insertion. If pos is beyond list length, temp or temp.next can be nil.
  2. Step 2: Identify missing nil checks

    Accessing temp.next.prev without checking if temp.next is nil can cause runtime panic.
  3. Final Answer:

    No check if temp or temp.next is nil before accessing pointers -> Option C
  4. Quick Check:

    Missing nil checks cause runtime errors [OK]
Hint: Always check for nil before accessing next or prev pointers [OK]
Common Mistakes:
  • Ignoring nil pointer checks causing crashes
  • Incorrect pointer assignments order
  • Returning wrong node pointer
5. You have a doubly linked list: 5 <-> 15 <-> 25 <-> 35. You want to insert a node with value 20 at position 3. After insertion, what will be the correct order of nodes and how should pointers be updated?
hard
A. 5 <-> 20 <-> 15 <-> 25 <-> 35; update 5.next to 20, 20.prev to 5, 20.next to 15, 15.prev to 20
B. 5 <-> 15 <-> 25 <-> 20 <-> 35; update 25.next to 20, 20.prev to 25, 20.next to 35, 35.prev to 20
C. 20 <-> 5 <-> 15 <-> 25 <-> 35; update head to 20, 20.next to 5, 5.prev to 20
D. 5 <-> 15 <-> 20 <-> 25 <-> 35; update 15.next to 20, 20.prev to 15, 20.next to 25, 25.prev to 20

Solution

  1. Step 1: Determine correct insertion position

    Position 3 means node with value 20 goes between nodes 15 (pos 2) and 25 (pos 3).
  2. Step 2: Update pointers for insertion

    Set 15.next to new node 20, 20.prev to 15, 20.next to 25, and 25.prev to 20 to maintain list integrity.
  3. Final Answer:

    5 <-> 15 <-> 20 <-> 25 <-> 35; update 15.next to 20, 20.prev to 15, 20.next to 25, 25.prev to 20 -> Option D
  4. Quick Check:

    Insert between 15 and 25 with pointer updates = C [OK]
Hint: Insert between nodes and update four pointers correctly [OK]
Common Mistakes:
  • Swapping nodes or inserting at wrong position
  • Forgetting to update prev pointers
  • Incorrectly updating next pointers causing broken links
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