Binary Search on Singly Linked List

Given a singly linked list and a key, find key using binary search approach.
To perform Binary search based on Divide and Conquer Algorithm, determination of middle element is important. Binary Search is usually fast and efficient for arrays because accessing the middle index between two given indices is easy and fast(Time Complexity O(1)). But memory allocation for singly linked list is dynamic and non contiguous, which makes finding the middle element difficult. One approach could be of using skip list, one could be traversing the linked list using one pointer.

Prerequisite : Finding middle of a linked list.

Note : The approach and implementation provided below are to show how Binary Search can be implemented on linked list. The implementation takes O(n) time.

Approach :

  • Here, start node(set to Head of list), and the last node(set to NULL initially) are given.
  • Middle is calculated using two pointers approach.
  • If middle’s data matches the required value of search, return it.
  • Else if midele’s data < value, move to upper half(setting last to midele's next).
  • Else go to lower half(setting last to middle).
  • The condition to come out is, either element found or entire list is traversed. When entire list is traversed, last points to start i.e. last -> next == start.

In main function, function InsertAtHead inserts value at the beginning of linked list. Inserting such values(for sake of simplicity) so that the list created is sorted.



Examples :

Input : Enter value to search : 7
Output : Found

Input : Enter value to search : 12
Output : Not Found
// CPP code to implement binary search
// on Singly Linked List
#include<stdio.h>
#include<stdlib.h>

struct Node
{
    int data;
    struct Node* next;
};

Node *newNode(int x)
{
    struct Node* temp = new Node;
    temp->data = x;
    temp->next = NULL;
    return temp;
}

// function to find out middle element
struct Node* middle(Node* start, Node* last)
{
    if (start == NULL)
        return NULL;

    struct Node* slow = start;
    struct Node* fast = start -> next;

    while (fast != last)
    {
        fast = fast -> next;
        if (fast != last)
        {
            slow = slow -> next;
            fast = fast -> next;
        }
    }

    return slow;
}

// Function for implementing the Binary
// Search on linked list
struct Node* binarySearch(Node *head, int value)
{
    struct Node* start = head;
    struct Node* last = NULL;

    do
    {
        // Find middle
        Node* mid = middle(start, last);

        // If middle is empty
        if (mid == NULL)
            return NULL;

        // If value is present at middle
        if (mid -> data == value)
            return mid;

        // If value is more than mid
        else if (mid -> data < value)
            start = mid -> next;

        // If value is less than mid.
        else
            last = mid;

    } while (last == NULL ||
             last -> next != start);

    // value not present
    return NULL;
}

// Driver Code
int main()
{
    Node *head = newNode(1);
    head->next = newNode(4);
    head->next->next = newNode(7);
    head->next->next->next = newNode(8);
    head->next->next->next->next = newNode(9);
    head->next->next->next->next->next = newNode(10);
    int value = 7;
    if (binarySearch(head, value) == NULL)
        printf("Value not present\n");
    else
        printf("Present");
    return 0;
}
Output:

Present

Time Complexity : O(n)





A learner in process

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Recommended Posts:



2.3 Average Difficulty : 2.3/5.0
Based on 3 vote(s)