Search in a Linked List

Say you have a linked list of student IDs. You want to know if 42 is in there. With an array you could just check arr[3] and jump straight to any spot. A linked list does not let you do that. There is no index to jump to. You have to start at the front. Then you follow the links one by one until you find the value or run out of nodes. That walk is what searching a linked list means.

📚 What Is Searching a Linked List?

Searching means looking for a target value inside the list. Then you tell the caller where it is.

A linked list is a chain of nodes. Each node holds a value and a link to the next node. We call that link a pointer. The first node is called the head. The last node points to nothing. We write that as null (or NULL, or None, depending on the language).

To search, you begin at the head. You look at the current node’s value. If it matches your target, you are done. If not, you move to the next node using its link. You keep going until one of two things happens. Either you find the value, or you hit null. Hitting null means the value was not there.

Here is the picture of a list and the target we are hunting for.

Head

10

20

30

40

null

If we search for 30, we check 10, then 20, then 30, and stop. That took three steps.

Note

An array gives you direct access. You can read the element at any index in one step. A linked list only gives you the head. So the only way in is to walk the chain. That is why searching a linked list is slower than searching by index in an array.

🎯 What Search Can Find

When you search, one of these will happen.

  • Found — some node along the way holds the target. You return its position so the caller knows where it sits.
  • Not found — you reach null without ever matching. There is nothing left to check. So you return -1.

We will count positions starting from 0. So the head is position 0. The next node is position 1, and so on. This matches how arrays are indexed. That keeps things familiar.

Tip

Returning -1 for “not found” is a common habit across data structures. A valid position is never negative. So -1 is a safe signal that the value is missing.

📝 Steps to Search a Linked List

Here is the plan we will turn into code.

  1. Start with a pointer at the head and a counter set to 0.
  2. If the current node is null, stop. The list ended, so return -1.
  3. Compare the current node’s value with the target.
  4. If they match, return the counter. That is the position.
  5. If they do not match, move the pointer to the next node and add 1 to the counter.
  6. Repeat from step 2.

The key idea is simple. You can never skip ahead. You can only move forward one link at a time. That single rule shapes the whole algorithm.

💻 Search in 5 Languages

Each program below builds a small list 10 -> 20 -> 30 -> 40. Then it searches for 30, which is in the list. It also searches for 99, which is not. The search function returns the position or -1.

search_linked_list.py
# A node holds a value and a link to the next node.
class Node:
def __init__(self, value):
self.data = value
self.next = None
# Walk from head, return the position of target, or -1 if missing.
def search(head, target):
position = 0
current = head
while current is not None: # stop when we run out of nodes
if current.data == target: # found it?
return position
current = current.next # move one link forward
position += 1
return -1 # reached the end, not found
# Build 10 -> 20 -> 30 -> 40
head = Node(10)
head.next = Node(20)
head.next.next = Node(30)
head.next.next.next = Node(40)
print("Position of 30:", search(head, 30))
print("Position of 99:", search(head, 99))

The output of the above code will be:

Output
Position of 30: 2
Position of 99: -1

Notice the shape is the same in every language. You hold a current pointer. You keep a position counter. Then you loop forward until you match or reach the end.

Note

Time and space. Searching is O(n) time. In the worst case the target sits at the very end, or it is missing. Either way you touch every node. It is O(1) space because you only use one extra pointer and one counter, no matter how long the list gets.

⏱️ Complexity at a Glance

Here is how the cost breaks down by case.

Case What Happens Time
Best case Target is the head node O(1)
Worst case Target is last, or not in the list O(n)
Average case Target sits somewhere in the middle O(n)
Space One pointer and one counter only O(1)

⚠️ Common Mistakes

Watch out for these slips when you write the search yourself.

  • Forgetting the null check. If you read current.data before checking that current is not null, your program crashes the moment it walks past the last node. Always test for null first.
  • Returning 0 instead of -1 for not found. Position 0 is a real spot, the head. Use -1 so the caller can tell “missing” apart from “found at the front”.
  • Not moving the pointer. If you forget current = current.next, the loop checks the same node forever and never ends. Make sure every pass steps forward.
  • Starting the counter wrong. If you want 0-based positions, the counter must start at 0 and increase only after you move. Mixing this up shifts every result by one.

🧩 What You’ve Learned

✅ Searching a linked list means walking from the head, node by node, until you match the target or reach null.

✅ You cannot jump to an index like an array. You must follow the links one step at a time.

✅ A search function returns the position when found, or -1 when the value is not in the list.

✅ The cost is O(n) time in the worst case and O(1) space, since you only keep one pointer and one counter.

✅ The classic bugs are skipping the null check, forgetting to move the pointer, and returning 0 instead of -1.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    Why can't you jump straight to the middle of a linked list the way you can with an array index?

    Why: Each node only holds a link to the next one, so the only way through is to start at the head and walk forward.

  2. 2

    What should the search function return when the target value is not in the list?

    Why: Returning -1 signals 'not found' because a valid position is never negative.

  3. 3

    What is the worst-case time complexity of searching a singly linked list?

    Why: In the worst case the target is at the end or missing, so you must check every node, which is O(n).

  4. 4

    What happens if you forget the line that moves current to current.next inside the loop?

    Why: Without advancing the pointer, current never changes, so the loop condition stays true forever.

🚀 What’s Next?

Share & Connect