给定一个单向链表和一个键,使用二分搜索方法找到键。
为了执行基于分而治之算法的二分搜索,中间元素的确定很重要。二分搜索通常对数组快速有效,因为访问两个给定索引之间的中间索引既简单又快速(时间复杂度为 O(1))。但是单向链表的内存分配是动态的且不连续的,这使得查找中间元素变得困难。一种方法可能是使用跳过列表,一种可能是使用一个指针遍历链表。
先决条件:找到链表的中间。
注意:下面提供的方法和实现是为了展示如何在链表上实现二分搜索。实现需要 O(n) 时间。
方法 :
- 这里给出了起始节点(设置为列表的头部)和最后一个节点(最初设置为 NULL)。
- Middle 是使用两个指针的方法计算的。
- 如果中间的数据与搜索所需的值匹配,则返回它。
- 否则如果中间的数据<值,移动到上半部分(设置开始到中间的下一个)。
- 否则转到下半部分(设置最后到中间)。
- 出来的条件是,找到元素或遍历整个列表。当遍历整个列表时,last 指向开始,即 last -> next == start。
在 main函数,函数InsertAtHead在链表的开头插入值。插入这样的值(为了简单起见),以便对创建的列表进行排序。
例子 :
Input : Enter value to search : 7
Output : Found
Input : Enter value to search : 12
Output : Not Found
C++
// CPP code to implement binary search
// on Singly Linked List
#include
#include
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 the value is less than mid.
else
last = mid;
} while (last == NULL ||
last != 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;
}
Java
// Java code to implement binary search
// on Singly Linked List
// Node Class
class Node
{
int data;
Node next;
// Constructor to create a new node
Node(int d)
{
data = d;
next = null;
}
}
class BinarySearch
{
// function to insert a node at the beginning
// of the Singaly Linked List
static Node push(Node head, int data)
{
Node newNode = new Node(data);
newNode.next = head;
head = newNode;
return head;
}
// Function to find middle element
// using Fast and Slow pointers
static Node middleNode(Node start, Node last)
{
if (start == null)
return null;
Node slow = start;
Node fast = start.next;
while (fast != last)
{
fast = fast.next;
if (fast != last)
{
slow = slow.next;
fast = fast.next;
}
}
return slow;
}
// function to insert a node at the beginning
// of the Singly Linked List
static Node binarySearch(Node head, int value)
{
Node start = head;
Node last = null;
do
{
// Find Middle
Node mid = middleNode(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 less than mid
else if (mid.data > value)
{
start = mid.next;
}
// If the value is more than mid.
else
last = mid;
} while (last == null || last != start);
// value not present
return null;
}
// Driver Code
public static void main(String[] args)
{
Node head = null;
// Using push() function to
// convert singly linked list
// 10 -> 9 -> 8 -> 7 -> 4 -> 1
head = push(head, 1);
head = push(head, 4);
head = push(head, 7);
head = push(head, 8);
head = push(head, 9);
head = push(head, 10);
int value = 7;
if (binarySearch(head, value) == null)
{
System.out.println("Value not present");
}
else
{
System.out.println("Present");
}
}
}
// This code is contributed by Vivekkumar Singh
Python
# Python code to implement binary search
# on Singly Linked List
# Link list node
class Node:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
def newNode(x):
temp = Node(0)
temp.data = x
temp.next = None
return temp
# function to find out middle element
def middle(start, last):
if (start == None):
return None
slow = start
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
def binarySearch(head,value):
start = head
last = None
while True :
# Find middle
mid = middle(start, last)
# If middle is empty
if (mid == None):
return None
# If value is present at middle
if (mid . data == value):
return mid
# If value is more than mid
elif (mid . data < value):
start = mid . next
# If the value is less than mid.
else:
last = mid
if not (last == None or last != start):
break
# value not present
return None
# Driver Code
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)
value = 7
if (binarySearch(head, value) == None):
print("Value not present\n")
else:
print("Present")
# This code is contributed by Arnab Kundu
C#
// C# code to implement binary search
// on Singly Linked List
using System;
// Node Class
public class Node
{
public int data;
public Node next;
// Constructor to create a new node
public Node(int d)
{
data = d;
next = null;
}
}
class BinarySearch
{
// function to insert a node at the beginning
// of the Singaly Linked List
static Node push(Node head, int data)
{
Node newNode = new Node(data);
newNode.next = head;
head = newNode;
return head;
}
// Function to find middle element
// using Fast and Slow pointers
static Node middleNode(Node start, Node last)
{
if (start == null)
return null;
Node slow = start;
Node fast = start.next;
while (fast != last)
{
fast = fast.next;
if (fast != last)
{
slow = slow.next;
fast = fast.next;
}
}
return slow;
}
// function to insert a node at the beginning
// of the Singly Linked List
static Node binarySearch(Node head, int value)
{
Node start = head;
Node last = null;
do
{
// Find Middle
Node mid = middleNode(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 less than mid
else if (mid.data > value)
{
start = mid.next;
}
// If the value is more than mid.
else
last = mid;
} while (last == null || last != start);
// value not present
return null;
}
// Driver Code
public static void Main(String []args)
{
Node head = null;
// Using push() function to
// convert singly linked list
// 10 -> 9 -> 8 -> 7 -> 4 -> 1
head = push(head, 1);
head = push(head, 4);
head = push(head, 7);
head = push(head, 8);
head = push(head, 9);
head = push(head, 10);
int value = 7;
if (binarySearch(head, value) == null)
{
Console.WriteLine("Value not present");
}
else
{
Console.WriteLine("Present");
}
}
}
// This code is contributed by Arnab Kundu
Javascript
输出:
Present
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。