Binary Search for Object Search
Problem Statement
Write a Java program that extends the Binary Search algorithm to find a Student object by its id in a sorted array of Student objects, where the array is sorted by id in ascending order. The program should count the number of comparisons made during the search and test with a sample dataset, including arrays of different sizes (e.g., 10, 100, 1000) and various target id values (present, absent, middle element). The Student class should have fields id (integer) and name (string), and Binary Search will compare id values to locate the target. You can visualize this as searching for a student by their ID in a sorted roster, halving the search range with each comparison.
Input:
- A sorted array of Student objects (by
idin ascending order) and a targetidto find. Output: The index of the Student object with the targetid(or -1 if not found), the number of comparisons made, and a string representation of the input array for verification. Constraints: - The array length
nis between 0 and 10^5. - Student
idvalues and targetidare integers in the range [1, 10^9]. - The input array is sorted by
idin ascending order. Example: - Input: array = [Student(1, "Alice"), Student(3, "Bob"), Student(5, "Charlie"), Student(7, "David")], targetId = 3
- Output:
- Input Array: [(1, Alice), (3, Bob), (5, Charlie), (7, David)]
- Target ID: 3
- Index: 1
- Comparisons: 2
- Explanation: Binary Search finds the Student with
id=3at index 1 after 2 comparisons. - Input: array = [Student(1, "Alice"), Student(2, "Bob")], targetId = 4
- Output:
- Input Array: [(1, Alice), (2, Bob)]
- Target ID: 4
- Index: -1
- Comparisons: 2
- Explanation: Binary Search returns -1 as no Student with
id=4is found after 2 comparisons.
Pseudocode
CLASS Student
DECLARE id as integer
DECLARE name as string
FUNCTION toString()
RETURN "(" + id + ", " + name + ")"
ENDFUNCTION
ENDCLASS
FUNCTION binarySearch(arr, targetId)
SET comparisons to 0
SET left to 0
SET right to length of arr - 1
WHILE left <= right
SET mid to floor((left + right) / 2)
INCREMENT comparisons
IF arr[mid].id equals targetId THEN
RETURN mid, comparisons
ELSE IF arr[mid].id < targetId THEN
SET left to mid + 1
ELSE
SET right to mid - 1
ENDIF
ENDWHILE
RETURN -1, comparisons
ENDFUNCTION
FUNCTION toString(arr)
CREATE result as new StringBuilder
APPEND "[" to result
FOR each student in arr
APPEND student.toString() to result
IF student is not last THEN
APPEND ", " to result
ENDIF
ENDFOR
APPEND "]" to result
RETURN result as string
ENDFUNCTION
FUNCTION main()
SET sizes to [10, 100, 1000]
FOR each size in sizes
SET testCases to array of (array, targetId) pairs
FOR each testCase in testCases
PRINT test case details
SET arr to testCase sorted Student array
SET targetId to testCase target
CALL binarySearch(arr, targetId) to get index, comparisons
PRINT input array, targetId, index, comparisons
ENDFOR
ENDFOR
ENDFUNCTION
Algorithm Steps
- Define
Studentclass: a. Includeid(integer) andname(string) fields. b. Provide atoStringmethod to format as(id, name). - Define
binarySearch: a. Initialize comparisons to 0,leftto 0,rightto n-1. b. Whileleft<=right:- Compute
midas the floor of(left + right) / 2. - Increment comparisons and check if
arr[mid].idequalstargetId. - If equal, return
midand comparisons. - If
arr[mid].id<targetId, setlefttomid + 1. - If
arr[mid].id>targetId, setrighttomid - 1. c. Return -1 and comparisons if not found.
- Compute
- Define
toString: a. Convert array of Student objects to a string, limiting output for large arrays. - In
main, test with: a. Array sizes: 10, 100, 1000 (sorted byid). b. For each size, test:- Target
idpresent in the middle (average case). - Target
idabsent. - Target
idas the middle element (exact middle). c. Generate sorted Student arrays with uniqueidvalues using a fixed seed.
- Target
Java Implementation
import java.util.*;
public class BinarySearchObjectSearch {
// Student class
static class Student {
int id;
String name;
Student(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "(" + id + ", " + name + ")";
}
}
// Performs Binary Search on Student array by id
public int[] binarySearch(Student[] arr, int targetId) {
int comparisons = 0;
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // Avoid overflow
comparisons++;
if (arr[mid].id == targetId) {
return new int[]{mid, comparisons};
} else if (arr[mid].id < targetId) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return new int[]{-1, comparisons};
}
// Converts Student array to string
public String toString(Student[] arr) {
StringBuilder result = new StringBuilder("[");
int limit = Math.min(arr.length, 10); // Limit output for large arrays
for (int i = 0; i < limit; i++) {
result.append(arr[i].toString());
if (i < limit - 1) {
result.append(", ");
}
}
if (arr.length > limit) {
result.append(", ...]");
} else {
result.append("]");
}
return result.toString();
}
// Generates sorted Student array
private Student[] generateStudentArray(int n) {
Random rand = new Random(42); // Fixed seed for reproducibility
Student[] arr = new Student[n];
String[] names = {"Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace", "Hannah", "Ivy", "Jack"};
// Ensure unique IDs by using a sorted sequence
for (int i = 0; i < n; i++) {
int id = i + 1; // IDs from 1 to n
String name = names[rand.nextInt(names.length)]; // Random name
arr[i] = new Student(id, name);
}
// Array is already sorted by ID
return arr;
}
// Helper class for test cases
static class TestCase {
Student[] arr;
int targetId;
String description;
TestCase(Student[] arr, int targetId, String description) {
this.arr = arr;
this.targetId = targetId;
this.description = description;
}
}
// Main method to test Binary Search on Student objects
public static void main(String[] args) {
BinarySearchObjectSearch searcher = new BinarySearchObjectSearch();
int[] sizes = {10, 100, 1000};
// Run test cases
for (int size : sizes) {
System.out.println("Array Size: " + size);
Student[] arr = searcher.generateStudentArray(size);
System.out.println("Input Array: " + searcher.toString(arr));
TestCase[] testCases = {
new TestCase(arr, arr[size / 2].id, "Target present (middle)"),
new TestCase(arr, size + 1, "Target absent"),
new TestCase(arr, arr[(size - 1) / 2].id, "Target middle element")
};
for (int i = 0; i < testCases.length; i++) {
System.out.println("Test case " + (i + 1) + ": " + testCases[i].description);
Student[] sortedArr = testCases[i].arr.clone(); // Copy to preserve original
int targetId = testCases[i].targetId;
System.out.println("Target ID: " + targetId);
int[] result = searcher.binarySearch(sortedArr, targetId);
System.out.println("Index: " + result[0]);
System.out.println("Comparisons: " + result[1] + "\n");
}
}
}
}
Output
Running the main method produces (example output, random names fixed by seed):
Array Size: 10
Input Array: [(1, Charlie), (2, Alice), (3, Jack), (4, Ivy), (5, Eve), (6, Grace), (7, David), (8, Bob), (9, Hannah), (10, Eve)]
Test case 1: Target present (middle)
Target ID: 6
Index: 5
Comparisons: 2
Test case 2: Target absent
Target ID: 11
Index: -1
Comparisons: 4
Test case 3: Target middle element
Target ID: 5
Index: 4
Comparisons: 3
Array Size: 100
Input Array: [(1, Charlie), (2, Alice), (3, Jack), (4, Ivy), (5, Eve), (6, Grace), (7, David), (8, Bob), (9, Hannah), (10, Eve), ...]
Test case 1: Target present (middle)
Target ID: 51
Index: 50
Comparisons: 7
Test case 2: Target absent
Target ID: 101
Index: -1
Comparisons: 7
Test case 3: Target middle element
Target ID: 50
Index: 49
Comparisons: 7
Array Size: 1000
Input Array: [(1, Charlie), (2, Alice), (3, Jack), (4, Ivy), (5, Eve), (6, Grace), (7, David), (8, Bob), (9, Hannah), (10, Eve), ...]
Test case 1: Target present (middle)
Target ID: 501
Index: 500
Comparisons: 10
Test case 2: Target absent
Target ID: 1001
Index: -1
Comparisons: 10
Test case 3: Target middle element
Target ID: 500
Index: 499
Comparisons: 10
Explanation:
- Size 10: Finds
id=6at index 5 (~2 comparisons), absentid=11(~4 comparisons), middleid=5at index 4 (~3 comparisons). - Size 100: Finds
id=51at index 50 (~7 comparisons), absentid=101(~7 comparisons), middleid=50at index 49 (~7 comparisons). - Size 1000: Finds
id=501at index 500 (~10 comparisons), absentid=1001(~10 comparisons), middleid=500at index 499 (~10 comparisons). - Comparisons scale logarithmically (~log n) due to Binary Search’s efficiency.
How It Works
- Student Class:
- Stores
idandname, with atoStringmethod for output formatting.
- Stores
- binarySearch:
- Adapts Binary Search to compare
arr[mid].idwithtargetId. - Uses
leftandrightpointers to halve the search range, incrementing comparisons. - Returns
[index, comparisons]or[-1, comparisons].
- Adapts Binary Search to compare
- generateStudentArray:
- Creates an array of Student objects with unique
idvalues (1 to n) and random names.
- Creates an array of Student objects with unique
- toString: Formats Student array, limiting to 10 elements.
- Example Trace (Size 10, Target ID=6):
- Array: [(1, Charlie), (2, Alice), (3, Jack), (4, Ivy), (5, Eve), (6, Grace), (7, David), (8, Bob), (9, Hannah), (10, Eve)].
- Initial: left=0, right=9, mid=4, arr[4].id=5 < 6, comparisons=1, left=5.
- Next: left=5, right=9, mid=7, arr[7].id=8 > 6, comparisons=2, right=6.
- Next: left=5, right=6, mid=5, arr[5].id=6 = 6, comparisons=3, return [5, 3].
- Main Method: Tests sizes 10, 100, 1000 with present, absent, and middle
idtargets, displaying results and comparisons.
Complexity Analysis Table
| Operation | Time Complexity | Space Complexity |
|---|---|---|
| binarySearch | O(log n) | O(1) |
| toString | O(n) | O(n) |
| generateStudentArray | O(n) | O(n) |
Note:
- n is the array length.
- Time complexity: O(log n) for binarySearch (halves search range); O(n) for toString and generateStudentArray (linear iteration).
- Space complexity: O(1) for binarySearch (constant extra space); O(n) for toString (string builder) and generateStudentArray (array storage).
- Binary Search remains efficient for object searches when sorted by a key.
✅ Tip: Binary Search can be extended to search for objects by a key (e.g.,
id) in sorted arrays, maintaining O(log n) efficiency. Ensure the array is sorted by the search key to achieve correct results.
⚠ Warning: The array must be sorted by the
idfield in ascending order. Incorrect sorting or duplicateidvalues may lead to unpredictable results. Use unique keys or handle duplicates explicitly if needed.