0% found this document useful (0 votes)
11 views4 pages

Java Sorting and Searching Algorithms

The document provides an overview of fundamental searching and sorting algorithms implemented in Java, including Binary Search, Bubble Sort, Selection Sort, Insertion Sort, Merge Sort, Quick Sort, and Linear Search. Each algorithm is accompanied by code examples that demonstrate its functionality. This resource is designed for individuals preparing for interviews or seeking to practice coding skills.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views4 pages

Java Sorting and Searching Algorithms

The document provides an overview of fundamental searching and sorting algorithms implemented in Java, including Binary Search, Bubble Sort, Selection Sort, Insertion Sort, Merge Sort, Quick Sort, and Linear Search. Each algorithm is accompanied by code examples that demonstrate its functionality. This resource is designed for individuals preparing for interviews or seeking to practice coding skills.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Java Algorithms - Key Concepts & Examples

1. Binary Search

public class BinarySearch {


public static int binarySearch(int[] arr, int key) {
int left = 0, right = [Link] - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == key) return mid;
if (arr[mid] < key) left = mid + 1;
else right = mid - 1;
}
return -1;
}

public static void main(String[] args) {


int[] arr = {1, 3, 5, 7, 9, 11};
int key = 7;
int result = binarySearch(arr, key);
[Link]("Element found at index: " + result);
}
}

2. Bubble Sort

public class BubbleSort {


public static void bubbleSort(int[] arr) {
int n = [Link];
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}

public static void main(String[] args) {


int[] arr = {5, 1, 4, 2, 8};
bubbleSort(arr);
for (int i : arr) [Link](i + " ");

1
}
}

3. Selection Sort

public class SelectionSort {


public static void selectionSort(int[] arr) {
int n = [Link];
for (int i = 0; i < n-1; i++) {
int min_idx = i;
for (int j = i+1; j < n; j++) {
if (arr[j] < arr[min_idx]) min_idx = j;
}
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}

public static void main(String[] args) {


int[] arr = {64, 25, 12, 22, 11};
selectionSort(arr);
for (int i : arr) [Link](i + " ");
}
}

4. Insertion Sort

public class InsertionSort {


public static void insertionSort(int[] arr) {
int n = [Link];
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}

public static void main(String[] args) {


int[] arr = {12, 11, 13, 5, 6};
insertionSort(arr);

2
for (int i : arr) [Link](i + " ");
}
}

5. Merge Sort

public class MergeSort {


public static void merge(int[] arr, int l, int m, int r) {
int n1 = m - l + 1;
int n2 = r - m;
int[] L = new int[n1];
int[] R = new int[n2];
for (int i = 0; i < n1; i++) L[i] = arr[l + i];
for (int j = 0; j < n2; j++) R[j] = arr[m + 1 + j];
int i = 0, j = 0, k = l;
while (i < n1 && j < n2) {
arr[k++] = (L[i] <= R[j]) ? L[i++] : R[j++];
}
while (i < n1) arr[k++] = L[i++];
while (j < n2) arr[k++] = R[j++];
}

public static void mergeSort(int[] arr, int l, int r) {


if (l < r) {
int m = l + (r-l)/2;
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
}

public static void main(String[] args) {


int[] arr = {12, 11, 13, 5, 6, 7};
mergeSort(arr, 0, [Link]-1);
for (int i : arr) [Link](i + " ");
}
}

6. Quick Sort

public class QuickSort {


public static int partition(int[] arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {

3
if (arr[j] < pivot) {
i++;
int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;
}
}
int temp = arr[i+1]; arr[i+1] = arr[high]; arr[high] = temp;
return i + 1;
}

public static void quickSort(int[] arr, int low, int high) {


if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi-1);
quickSort(arr, pi+1, high);
}
}

public static void main(String[] args) {


int[] arr = {10, 7, 8, 9, 1, 5};
quickSort(arr, 0, [Link]-1);
for (int i : arr) [Link](i + " ");
}
}

7. Linear Search

public class LinearSearch {


public static int linearSearch(int[] arr, int key) {
for (int i = 0; i < [Link]; i++) {
if (arr[i] == key) return i;
}
return -1;
}

public static void main(String[] args) {


int[] arr = {3, 4, 2, 7, 5};
int key = 7;
int result = linearSearch(arr, key);
[Link]("Element found at index: " + result);
}
}

This document covers basic searching and sorting algorithms in Java with ready-to-run code
examples, suitable for interviews and practice.

Common questions

Powered by AI

Merge sort achieves better time complexity by employing a divide-and-conquer strategy. It recursively divides the array into halves until each sub-array contains a single element or is empty. Then, it merges these sub-arrays back together in order such that each merge operation results in a sorted order. This recursive division and merging result in a consistent time complexity of O(n log n), superior to the O(n^2) time complexity of simple iterative algorithms like bubble or insertion sort .

The 'divide and conquer' concept in algorithms involves breaking a problem into smaller sub-problems, solving each independently, and then combining solutions for the final result. In merge sort, the array is recursively divided into two halves until each half is a single element; the 'conquer' phase merges these single elements into sorted sub-arrays using the merge function. Similarly, quick sort uses a pivot to divide the array into two partitions: items less than the pivot on one side and items more significant on the other, recursively sorting each partition. Both methods utilize 'divide and conquer' to break down and efficiently solve the sorting problem, although quick sort partitions the array during the divide phase itself .

Linear search is less efficient compared to binary search, especially in large datasets, because it involves checking each element of the array sequentially from the beginning until the target element is found or the entire array is traversed, resulting in a time complexity of O(n). In contrast, binary search takes advantage of the sorted nature of arrays, effectively cutting the search space in half with each comparison, resulting in a significantly more efficient O(log n) time complexity. This difference becomes particularly pronounced in large datasets where binary search can dramatically reduce the number of comparisons needed .

Bubble sort and selection sort differ in their approach: bubble sort repeatedly compares and swaps adjacent pairs of elements to "bubble" the largest unsorted element to its correct position at the array's end, while selection sort repeatedly selects the smallest (or largest) unsorted element and swaps it with the first unsorted element in the array. Despite their different approaches, both share the same computational efficiency of O(n^2) for average and worst cases, making them unsuitable for large datasets but easy to implement and understand .

The primary advantage of using insertion sort for partially sorted arrays is its efficiency in handling data that is almost sorted. In such cases, insertion sort can achieve an optimal time complexity of O(n) because it iterates through the array while maintaining a sorted subarray and needs to perform minimal or no shifts for elements that are already in order. This makes it particularly useful for real-time applications that frequently receive new data and require the list to remain partially sorted, outperforming other elementary sorting algorithms like bubble sort which generally operate at O(n^2).

Binary search minimizes the number of comparisons by repeatedly dividing the sorted array in half and comparing the target element with the middle element of each half. If the target element is equal to the middle element, the search is complete. If the target element is less, the search continues in the left half, discarding the right half. Conversely, if the target element is greater, the search continues in the right half. This halving process logarithmically reduces the number of elements to be considered, leading to a time complexity of O(log n).

The pivot element in quick sort plays a critical role by determining the division of elements into two sub-arrays. Elements less than the pivot are placed to its left, and those greater are placed to its right. This partitioning process is crucial for sorting and directly affects the efficiency of quick sort. Ideally, the pivot should divide the array into two equal halves to achieve optimal O(n log n) time complexity. However, the choice of pivot can lead to uneven splits and result in the worst-case time complexity of O(n^2), as in the case of already sorted or reverse-sorted arrays with the first or last element as a pivot .

The average-case time complexity of quick sort is O(n log n), making it very efficient for sorting. This assumes that the pivot divides the list into two roughly equal halves. The worst-case time complexity, however, is O(n^2), which occurs when the pivot ends up being the smallest or largest element consistently, as can happen when the array is already or nearly sorted. The primary factor influencing this difference is the choice of pivot: a poor choice, such as always picking the first or last element, can lead to unbalanced partitions and thus worse performance. Using techniques like the median-of-three rule for pivot selection can help mitigate these inefficiencies .

Bubble sort and insertion sort differ in terms of efficiency and operation. Bubble sort repeatedly steps through the array, compares adjacent elements, and swaps them if they are in the wrong order, resulting in a time complexity of O(n^2) on average and in the worst case. Conversely, insertion sort builds the sorted array one element at a time, moving the current element to its correct position in a sorted portion, also resulting in a time complexity of O(n^2) overall, but it can be more efficient for small or partially sorted arrays as it has a best-case time complexity of O(n) when the array is already sorted .

Selection sort is particularly useful in scenarios where memory usage is critical because it performs sorting with a constant amount of additional space (O(1) space complexity). Even though selection sort has a time complexity of O(n^2), making it inefficient for large lists, its minimal memory usage makes it suitable for embedded systems or applications where space is a bigger constraint than time .

You might also like