Java Sorting Algorithms — Step-by-Step with Iterations

🔢 Java Sorting Algorithms — Step-by-Step with Iterations

Sorting is a fundamental concept in programming and data structures.
Below are the five main sorting algorithms, explained in simple terms with visual examples, loop-by-loop walkthroughs, and complete Java programs.


🧮 1️⃣ Bubble Sort — Iteration by Iteration

💡 Concept

Bubble Sort repeatedly compares adjacent elements and swaps them if they’re in the wrong order.
With each pass, the largest element “bubbles” to the end of the array.


⚙️ How It Works

  1. Start from the beginning of the array.

  2. Compare adjacent elements.

  3. Swap if the left is greater than the right.

  4. Repeat until no more swaps are needed.


🧩 Example: [5, 4, 1, 3]

Initial Array:
[5, 4, 1, 3]

Pass 1

ComparisonOperationResult
Compare 5 & 4Swap[4, 5, 1, 3]
Compare 5 & 1Swap[4, 1, 5, 3]
Compare 5 & 3Swap[4, 1, 3, 5]
✅ Largest element (5) “bubbled” to end.

Pass 2

ComparisonOperationResult
Compare 4 & 1Swap[1, 4, 3, 5]
Compare 4 & 3Swap[1, 3, 4, 5]
✅ Second largest (4) in place.

Pass 3

ComparisonOperationResult
Compare 1 & 3No swap[1, 3, 4, 5]
✅ Sorted.


💻 Java Code

package com.vi.sort; import java.util.Arrays; public class BubbleSort { public static void main(String[] args) { int[] a = {5, 4, 1, 3}; System.out.println("Before Sorting: " + Arrays.toString(a)); doBubbleSort(a); System.out.println("After Sorting: " + Arrays.toString(a)); } public static void doBubbleSort(int[] a) { boolean sorted = false; int iteration = 1; while (!sorted) { sorted = true; System.out.println("Iteration " + iteration++ + ": " + Arrays.toString(a)); for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { int temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; sorted = false; } } } } }

🧾 Output

Before Sorting: [5, 4, 1, 3] Iteration 1: [5, 4, 1, 3] Iteration 2: [4, 1, 3, 5] Iteration 3: [1, 3, 4, 5] After Sorting: [1, 3, 4, 5]

🧠 Key Points

  • Each pass “bubbles” the largest remaining element to the end.

  • Works well for small datasets.

  • Time: O(n²), Space: O(1), Stable: ✅ Yes


🧩 2️⃣ Insertion Sort — Iteration by Iteration

💡 Concept

Insertion Sort builds a sorted portion of the array one element at a time.
Each element is compared backward and inserted into its correct position.


⚙️ How It Works

  1. Start from index 1.

  2. Compare it to elements before it.

  3. Shift larger elements to the right.

  4. Insert current element into correct place.


🧩 Example: [5, 4, 1, 3]


Iteration 1 (i = 1, key = 4)

Left sorted part: [5]

Compare key=4 with previous elements:

  • 4 < 5 → shift 5 →
    [5, 5, 1, 3]

Insert 4 into the empty slot:

➡️ [4, 5, 1, 3]


Iteration 2 (i = 2, key = 1)

Left sorted part: [4, 5]

Compare key=1 with previous elements:

  • 1 < 5 → shift → [4, 5, 5, 3]

  • 1 < 4 → shift → [4, 4, 5, 3]

Insert 1:

➡️ [1, 4, 5, 3]


Iteration 3 (i = 3, key = 3)

Left sorted part: [1, 4, 5]

Compare key=3 with previous elements:

  • 3 < 5 → shift → [1, 4, 5, 5]

  • 3 < 4 → shift → [1, 4, 4, 5]

  • Next element is 1 (1 < 3) → stop early

Insert 3:

➡️ [1, 3, 4, 5]


💻 Java Code

package com.vi.sort; import java.util.Arrays; public class InsertionSort { public static void main(String[] args) { int[] a = {5, 4, 1, 3}; System.out.println("Before Sorting: " + Arrays.toString(a)); doInsertionSort(a); System.out.println("After Sorting: " + Arrays.toString(a)); } public static void doInsertionSort(int[] a) { for (int i = 1; i < a.length; i++) { int key = a[i]; int j = i - 1; while (j >= 0 && a[j] > key) { a[j + 1] = a[j]; j--; } a[j + 1] = key; System.out.println("Iteration " + i + ": " + Arrays.toString(a)); } } }

🧾 Output

Iteration 1: [4, 5, 1, 3] Iteration 2: [1, 4, 5, 3] Iteration 3: [1, 3, 4, 5]

🧠 Key Points

  • Works best on nearly sorted arrays.

  • Time: O(n²), Space: O(1), Stable: ✅ Yes

  • Ideal for real-time insertion problems.


🧩 3️⃣ Selection Sort — Iteration by Iteration

💡 Concept

Selection Sort repeatedly finds the smallest element from the unsorted part and places it at the start.


⚙️ How It Works

  1. Loop through the array to find the smallest.

  2. Swap it with the first unsorted element.

  3. Move the sorted boundary forward.


🧩 Example: [5, 4, 1, 3]

PassSmallestSwapResult
111 ↔ 5[1, 4, 5, 3]
233 ↔ 4[1, 3, 5, 4]
344 ↔ 5[1, 3, 4, 5]
✅ Sorted [1, 3, 4, 5]



💻 Java Code

package com.vi.sort; import java.util.Arrays; public class SelectionSort { public static void main(String[] args) { int[] a = {5, 4, 1, 3}; System.out.println("Before Sorting: " + Arrays.toString(a)); doSelectionSort(a); System.out.println("After Sorting: " + Arrays.toString(a)); } public static void doSelectionSort(int[] a) { for (int i = 0; i < a.length - 1; i++) { int min = i; for (int j = i + 1; j < a.length; j++) { if (a[j] < a[min]) { min = j; } } int temp = a[min]; a[min] = a[i]; a[i] = temp; System.out.println("Iteration " + (i + 1) + ": " + Arrays.toString(a)); } } }

🧾 Output

Iteration 1: [1, 4, 5, 3] Iteration 2: [1, 3, 5, 4] Iteration 3: [1, 3, 4, 5]

🧠 Key Points

  • Simple but slow.

  • Time: O(n²), Space: O(1), Stable: ❌ No.

  • Best when minimizing swaps.


🧩 4️⃣ Merge Sort — Iteration by Iteration

💡 Concept

Merge Sort follows divide and conquer — splitting the array, sorting halves, and merging them.


⚙️ How It Works

  1. Divide the array into halves.

  2. Recursively sort each half.

  3. Merge the two sorted halves.


🧩 Example: [5, 4, 1, 3]

Divide → [5,4] [1,3] Sort → [4,5] [1,3] Merge → [1,3,4,5]

Merge process:
Left [4,5], Right [1,3]
1 < 4 → pick 1
3 < 4 → pick 3
Append remaining → [1,3,4,5]


💻 Java Code

package com.vi.sort; import java.util.Arrays; public class MergeSort { public static void main(String[] args) { int[] a = {5, 4, 1, 3}; System.out.println("Before Sorting: " + Arrays.toString(a)); mergeSort(a, 0, a.length - 1); System.out.println("After Sorting: " + Arrays.toString(a)); } public static void mergeSort(int[] a, int left, int right) { if (left < right) { int mid = (left + right) / 2; mergeSort(a, left, mid); mergeSort(a, mid + 1, right); merge(a, left, mid, right); } } public static void merge(int[] a, int left, int mid, int right) { int n1 = mid - left + 1, n2 = right - mid; int[] L = new int[n1]; int[] R = new int[n2]; for (int i = 0; i < n1; i++) L[i] = a[left + i]; for (int j = 0; j < n2; j++) R[j] = a[mid + 1 + j]; int i = 0, j = 0, k = left; while (i < n1 && j < n2) { if (L[i] <= R[j]) a[k++] = L[i++]; else a[k++] = R[j++]; } while (i < n1) a[k++] = L[i++]; while (j < n2) a[k++] = R[j++]; System.out.println("Merging step: " + Arrays.toString(a)); } }

🧾 Output

Before Sorting: [5, 4, 1, 3] Merging step: [4, 5, 1, 3] Merging step: [4, 5, 1, 3] Merging step: [1, 3, 4, 5] After Sorting: [1, 3, 4, 5]

🧠 Key Points

  • Time: O(n log n), Space: O(n)

  • Stable: ✅ Yes

  • Great for large datasets or linked lists.


🧩 5️⃣ Quick Sort — Iteration by Iteration

💡 Concept

Quick Sort also uses divide and conquer — but partitions around a pivot element.


⚙️ How It Works

  1. Choose a pivot.

  2. Partition the array around it.

  3. Recursively apply on left and right sides.


🧩 Example: [5, 4, 1, 3]

Step 1: Pivot = 3
→ Partition → [1, 3, 5, 4]
Step 2: Left [1] sorted, right [5,4] → Pivot = 4
→ Swap → [1, 3, 4, 5] ✅


💻 Java Code

package com.vi.sort; import java.util.Arrays; public class QuickSort { public static void main(String[] args) { int[] a = {5, 4, 1, 3}; System.out.println("Before Sorting: " + Arrays.toString(a)); quickSort(a, 0, a.length - 1); System.out.println("After Sorting: " + Arrays.toString(a)); } public static void quickSort(int[] a, int low, int high) { if (low < high) { int pi = partition(a, low, high); System.out.println("After partition (pivot index " + pi + "): " + Arrays.toString(a)); quickSort(a, low, pi - 1); quickSort(a, pi + 1, high); } } public static int partition(int[] a, int low, int high) { int pivot = a[high]; int i = low - 1; for (int j = low; j < high; j++) { if (a[j] < pivot) { i++; int temp = a[i]; a[i] = a[j]; a[j] = temp; } } int temp = a[i + 1]; a[i + 1] = a[high]; a[high] = temp; return i + 1; } }

🧾 Output

Before Sorting: [5, 4, 1, 3] After partition (pivot index 1): [1, 3, 5, 4] After partition (pivot index 3): [1, 3, 4, 5] After Sorting: [1, 3, 4, 5]

🧠 Key Points

  • Average: O(n log n), Worst: O(n²)

  • Space: O(log n)

  • Stable: ❌ No

  • Used internally in Arrays.sort() for primitives.


📊 Sorting Algorithm Summary Table

AlgorithmTime ComplexitySpace    StableBest Use
Bubble SortO(n²)O(1)            Educational, small datasets
Insertion SortO(n²)O(1)            Small or nearly sorted data
Selection SortO(n²)O(1)            Minimal swaps
Merge SortO(n log n)O(n)                Large or linked data
Quick SortO(n log n) avgO(log n)            Fast general-purpose sorting

🧭 Final Thoughts

  • 🧮 Bubble Sort → Great for beginners.

  • ✏️ Insertion Sort → Efficient for small, sorted data.

  • 🧲 Selection Sort → Minimal swaps, easy to implement.

  • ⚙️ Merge Sort → Predictable performance, always O(n log n).

  • Quick Sort → Industry favorite; excellent average speed.


Java ArrayList object creation best practice

Sometimes we can get java.lang.UnsupportedOperationException due to the bad coding practice while using Array. We can create ArrayList in multiple ways, here one thing we need to remind as new ArrayList<>() there is no fixed size and Arrays.asList(“test”) has the fixed size. Whenever we creates arrayList using Arrays.asList and appending another values will get ava.lang.UnsupportedOperationException.

Example here

package vinodvino;

 

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

 

public class ArrayTest {

 

public static void main(String args[]) {

    

List<String> firstArray=new ArrayList<>();

firstArray.add("Vinod");

firstArray.add("Shaji");

    System.out.println("FirstArrayValues"+firstArray);

 

 

List<String> secondArray=Arrays.asList("Vinod");

    secondArray.add("Shaji");

    System.out.println("SecondArrayValues"+secondArray);

 

 

}

}

 

Output

FirstArrayValues[Vinod, Shaji]
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at vinodvino.ArrayTest.main(ArrayTest.java:19)

 

In order to avoid this we can use array as 

 

List<String> secondArray=new ArrayList<>(Arrays.asList("Vinod"));

 

Spring Boot and Swagger 3 Example

How to Integrate Swagger (Springfox) with Spring Boot

A Clean, Simple Guide for Beginners

Documenting REST APIs is one of the most important parts of backend development. Instead of writing documentation manually, tools like Swagger allow you to automatically visualize, explore, and test your APIs from a browser.

In this article, we will walk through a simple and clean implementation of Swagger 2 using Springfox in a Spring Boot application.


🌟 What is Swagger?

Swagger is an open-source framework for designing, documenting, and testing REST APIs.

It provides:

  • ✔️ Automatic API documentation

  • ✔️ Interactive UI for testing endpoints

  • ✔️ A live API sandbox

  • ✔️ Zero manual documentation effort

Once Swagger is added, API consumers can discover endpoints, test requests, and understand request/response structures without reading any technical document.


🧱 Project Setup — Add Dependencies

Create a Spring Boot project and add the following dependencies in your pom.xml.

This example uses Spring Boot 1.4.1 and Springfox Swagger 2.2.2.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.vinod.test</groupId> <artifactId>springboot-swagger-test</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.1.RELEASE</version> </parent> <dependencies> <!-- Spring Boot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Springfox Swagger 2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.2.2</version> </dependency> <!-- Swagger UI --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.2.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

⚙️ Step 2 — Create Swagger Configuration

Create a new configuration class SwaggerConfig.java under com.vinod.test.

This class:

  • Enables Swagger

  • Defines API info (title, description, version, contact, etc.)

  • Sets endpoint filtering

package com.vinod.test; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.google.common.base.Predicate; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; import static springfox.documentation.builders.PathSelectors.regex; import static com.google.common.base.Predicates.or; @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket postsApi() { return new Docket(DocumentationType.SWAGGER_2) .groupName("public-api") .apiInfo(apiInfo()) .select() .paths(postPaths()) .build(); } private Predicate<String> postPaths() { return or(regex("/api/posts.*"), regex("/api/test.*")); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("SWAGGER API") .description("SWAGGER SIMPLE EXAMPLE") .termsOfServiceUrl("http://vinodkkumaran.blogspot.com/") .contact("kkvinod.kumaran@gmail.com") .license("KK VINOD License") .licenseUrl("kkvinod.kumaran@gmail.com") .version("1.0") .build(); } }

📝 Step 3 — Create a Sample REST Controller

This is a simple GET endpoint that Swagger will automatically document.

package com.vinod.test; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping(method = RequestMethod.GET, value = "/api/test") public String sayHelloWorld() { return "Hello world from Swagger Example"; } }

🚀 Step 4 — Create Spring Boot Main Class

package com.vinod.test; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MySwaggerApplication { public static void main(String[] args) { SpringApplication.run(MySwaggerApplication.class, args); } }

▶️ Step 5 — Run the Application

Start the Spring Boot app:

mvn spring-boot:run

Open your browser and go to:

👉 http://localhost:8080/swagger-ui.html

You will see Swagger UI with your GET /api/test endpoint documented and ready to test.


🖼️ How Swagger UI Looks



http://localhost:8080/swagger-ui.html

Enum Constructor example

📘 Java Enums with Constructors — A Simple & Clear Guide

Enums in Java are often misunderstood as simple lists of constants.
But Enums are actually powerful types — they can include fields, methods, and even constructors.

In this blog, we’ll explore how to use Enum constructors to attach data to each enum constant.
We’ll also walk through an example where each subject has a maximum mark.


✅ What Are Enums in Java?

enum stands for enumeration, and it represents a fixed set of constants.

Example:

enum Color { RED, GREEN, BLUE }

But Java enums are much more than constants.
They are full-fledged classes with:

  • Variables (fields)

  • Methods

  • Constructors


🎯 Why Use Constructors in Enums?

Sometimes, each enum constant needs to hold some extra information.

For example:

  • Days of week → working hours

  • Planets → mass, radius

  • Subjects → maximum marks

By using a constructor inside an enum, we can store additional data for each constant.


🧩 Example Use Case: Subjects and Maximum Marks

Suppose you want to store maximum marks for each subject:

SubjectCodeMaximum Mark
PhysicsP50
ChemistryC50
BiologyB75
MathM100

Instead of using separate variables or maps, we attach values directly to enum constants.


🧱 Text Diagram: How Enum with Constructor Works

┌───────────────────────────────┐ │ enum MaxMark │ ├───────────────────────────────┤ │ P(50) → maxmark = 50 │ │ C(50) → maxmark = 50 │ │ B(75) → maxmark = 75 │ │ M(100) → maxmark = 100 │ ├───────────────────────────────┤ │ getMaxmark() returns value │ └───────────────────────────────┘

Each constant calls the constructor with a different value.


🧑‍💻 Full Java Code Example

package com.vinod.test; /** * Example showing Java Enum with Constructor * Author: Vinod Kariyathungal Kumaran */ public class EnumConstructorExample { public static void main(String[] args) { // Print all subjects and their maximum marks for (MaxMark m : MaxMark.values()) { System.out.println("Subject code=" + m + " Maximum Mark " + m.getMaxmark()); } // Print a specific subject's maximum mark System.out.println("Physics Maximum Mark=" + MaxMark.P.getMaxmark()); } } enum MaxMark { P(50), C(50), B(75), M(100); private int maxmark; // Enum constructor MaxMark(int p) { maxmark = p; } // Getter method int getMaxmark() { return maxmark; } }

🟦 Explanation

🔹 1. Enum Constants with Values

P(50), C(50), B(75), M(100)

Each constant calls the constructor with a number (max mark).

🔹 2. Constructor

MaxMark(int p) { maxmark = p; }

This assigns the passed value to the internal variable.

🔹 3. Getter Method

int getMaxmark() { return maxmark; }

Used to read the stored value.


🖨️ Program Output

Subject code=P Maximum Mark 50 Subject code=C Maximum Mark 50 Subject code=B Maximum Mark 75 Subject code=M Maximum Mark 100 Physics Maximum Mark=50

🎉 Final Thoughts

Java Enums are more powerful than most people realize.
By adding constructors and fields, you can treat them like lightweight data holders — clean, readable, and type-safe.

This approach is perfect for:

✔ Subject mark mapping
✔ Error codes with descriptions
✔ HTTP status codes
✔ Pricing tiers
✔ Role definitions


Abstraction and Encapsulation difference in simple way

Abstraction vs Encapsulation (Explained for Backend Engineers)

Simple, Practical, and Use-Case Based

Understanding Abstraction and Encapsulation is essential for writing maintainable backend code.
Most interviewers ask this, and many developers mix them up.

Here is the clearest possible explanation.


1. What is Abstraction?

Hiding unnecessary details and exposing only essential behavior.
Abstraction answers the question:

“WHAT does this object do?”

It focuses on the capabilities of a system, not how it is implemented.

Think of abstraction as a contract.


Real-World Example (Simple)

You drive a car using:

  • Steering

  • Brake

  • Accelerator

You don’t need to know:

  • how fuel injectors work

  • how ABS works

  • internal engine mechanics

You only care about what the car can do → turn, slow, speed up.


Java Code Example — Abstraction

interface PaymentService { void pay(double amount); }

The interface says what can be done → pay.
Nothing about how payment actually happens.


2. What is Encapsulation?

Bundling data + methods and protecting internal details using access modifiers.
Encapsulation answers:

“HOW does this object do what it does?”

It focuses on controlling access and hiding implementation.


Real-World Example

A washing machine:

  • You select a mode (normal, deep wash)

  • Inside: motor speed, timers, water levels are controlled

You cannot directly change internal components → they’re encapsulated.


Java Code Example — Encapsulation

class PaymentProcessor { private double balance; // hidden data (encapsulation) public void addMoney(double amount) { balance += amount; } public double getBalance() { return balance; } }

Here:

  • balance is hidden

  • access only through getter/setter

  • internal logic protected from misuse


3. Key Difference (Simple Interview Answer)

FeatureAbstractionEncapsulation
MeaningHides complexityHides internal data
FocusWhat object doesHow object works
Achieved ByInterfaces, Abstract classesClasses, access modifiers (private, public)
PurposeExpose essential features onlyProtect data & maintain integrity
ExamplePaymentService.pay()private balance variable

4. Use Case for Backend Engineers

✅ Use Case: Payment System in a Microservice Architecture

Abstraction:

Expose only the required behavior to other services.

public interface PaymentGateway { TransactionResponse makePayment(double amount); }
  • Other microservices don’t care if payment is done via Stripe, PayPal, RazorPay →

  • Abstraction hides vendor-specific logic.


Encapsulation:

Protect internal state inside the payment processor.

class RazorPayProcessor implements PaymentGateway { private String apiKey; // encapsulated data private String secretKey; // encapsulated data @Override public TransactionResponse makePayment(double amount) { // internal API call logic (hidden) } }
  • API keys hidden

  • Authentication logic hidden

  • No external service can modify internal state


5. Text-Based Diagram (Perfect for Blog & Interview)

┌─────────────────────────────┐ │ ABSTRACTION │ │ "WHAT action is allowed?" │ │ │ │ Interface: PaymentGateway │ │ - makePayment() │ └─────────────────────────────┘ │ ▼ ┌─────────────────────────────┐ │ ENCAPSULATION │ │ "HOW is the action done?" │ │ │ │ Class: RazorPayProcessor │ │ - private apiKey │ │ - private secretKey │ │ - internal logic hidden │ └─────────────────────────────┘

6. Super-Simple Memory Trick

Abstraction = Remote Control
You can press the button → but you don’t know the internals.

Encapsulation = TV Circuit Box
Everything wired inside → protected from you touching it.


✅ Final 1-Line Summary (Best for Interview)

Abstraction defines what an object can do. Encapsulation defines how it does it while protecting the internal state.


 

 

 

 

Linear Search example


🔎 Linear Search (Sequential Search)

What problem are we solving?

Given an array and a target value (the “key”), find the index where the key occurs. If it isn’t present, report that clearly (commonly -1).

When should you use it?

  • Arrays or lists that are unsorted (binary search won’t help).

  • Small to medium collections where code simplicity matters.

  • One-off searches where building an index or sorting is overkill.

How it works (step by step)

  1. Start at index 0.

  2. Compare the current element to the key.

  3. If they match → return the index.

  4. Otherwise move to the next element and repeat.

  5. If you reach the end with no match → return -1.

Complexity

  • Time: O(n) in the worst/average case; O(1) best case (if the key is at index 0).

  • Space: O(1) (in-place, no extra memory).


Java Implementation





 




package com.vinod.test;

/**
 * LinearSearch (Sequential Search)
 *
 * Problem:
 *   Given an array and a key, return the index of the key if present; otherwise -1.
 *
 * Approach:
 *   Scan from left to right and compare each element with the key.
 *
 * Time Complexity:
 *   Worst/Average: O(n), Best: O(1) if the first element matches.
 *
 * Space Complexity:
 *   O(1)
 *
 * Notes:
 *   - Works on unsorted arrays.
 *   - For sorted arrays, consider Binary Search (O(log n)).
 */
public class LinearSearch {

    public static void main(String[] args) {
        int[] arr = { 1, 3, 5, 7, 9, 12, 16, 18 };

        int key1 = 5;
        int idx1 = indexOf(arr, key1);
        System.out.println("Key " + key1 + " found at index = " + idx1); // expected: 2

        int key2 = 10;
        int idx2 = indexOf(arr, key2);
        System.out.println("Key " + key2 + " found at index = " + idx2); // expected: -1
    }

    /**
     * Returns the zero-based index of {@code key} in {@code arr}, or -1 if not found.
     *
     * @param arr the array to scan (may be unsorted)
     * @param key the value to find
     * @return index of the key if present; otherwise -1
     */
    public static int indexOf(int[] arr, int key) {
        if (arr == null || arr.length == 0) {
            return -1; // handle null/empty safely
        }

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == key) {
                return i; // found
            }
        }
        return -1; // not found
    }
}

Binary search algorithm and example

🔍 Binary Search (Divide-and-Conquer Algorithm)

What problem are we solving?

When we have a sorted array, we often need to locate a specific value efficiently — for example, to find the index of a student ID or a product code.
Instead of scanning element by element like Linear Search (which takes O(n) time), Binary Search repeatedly divides the search space in half, achieving much faster performance.


🧠 How it works (step by step)

  1. Precondition: The array must already be sorted (either ascending or descending).

  2. Initialize two pointers:

    • start = 0 (beginning of the array)

    • end = arr.length - 1 (end of the array)

  3. Find the middle index:
    mid = (start + end) / 2

  4. Compare the middle element (arr[mid]) with the key you’re searching for:

    • If arr[mid] == key → ✅ Found → return mid

    • If key < arr[mid] → search left half → set end = mid - 1

    • If key > arr[mid] → search right half → set start = mid + 1

  5. Repeat until start > end.
    If the loop ends with no match, the key isn’t present → return -1.

 


package
com.vinod.test;


/**
 * Binary search use to find out the position of the elements for the given key.
 *
 * The Array should be either in ascending or decending order.
 *
 *@authorvinodkariyathungalkumaran
 *
 */
public class BinarySearch {

public static void main(String[] args) {
int[] arr = { 1, 3, 5, 7, 9, 12, 16, 18 };
System.out.println("Position of 5=" + getPositionUsingBinarySearch(arr, 5));

}

/**
     * Algorithm
     *
     *1) First get the array mid position, if mid position of the value equal to the search key will return that one
     *
     *2) Else if key is less the mid value our start value will be o and end value will be mid -1
     *
     *3) Else if the key is greater than the mid value we will mark our start value as mid value +1
     *
     * This activity we will do until the start and end values are equal.
     *
     *
     *@param arr
     *@param key
     *@return
     */
public static int getPositionUsingBinarySearch(int[] arr, int key) {
int start = 0;
int end = arr.length - 1;
while (start <= end) {
int mid = (start + end) / 2;
if (key == arr[mid]) {
return mid;
}
if (key < arr[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return -1;
}
}

Confusion Matrix + Precision/Recall (Super Simple, With Examples)

  Confusion Matrix + Precision/Recall (Super Simple, With Examples) 1) Binary Classification Setup Binary classification means the model p...

Featured Posts