Skip to main content
← All posts

Bitonic Sort: Mechanism, Complexity Analysis & Interactive Visualizer

Md. Harun-Or-RoshidNov 5, 20269 min readArticle
Bitonic Sort: Mechanism, Complexity Analysis & Interactive Visualizer
Parallel Sorting · Article 40 of 62

Bitonic Sort

A parallel comparison network sort: recursively builds bitonic sequences (first increasing, then decreasing) before merging them in parallel steps, optimized for GPU and hardware layouts.

How it works

Bitonic Sort, designed by Ken Batcher in 1968, is a comparison-based sorting network. A sequence is *bitonic* if it increases and then decreases, or vice-versa. Bitonic Sort operates by converting arbitrary inputs into bitonic sequences, then sorting them in parallel stages:

  1. Bitonic Preparation: Recursively sort the left half ascending and the right half descending. This merges the two halves into a single bitonic sequence.
  2. Bitonic Merger: Take a bitonic sequence of length \(k\). Compare each element in the first half with the corresponding element in the second half (index \(i\) vs. \(i + k/2\)). Swap them if they are in the wrong order. This step splits the array into two smaller bitonic halves.
  3. Recursive Merge: Apply the same merging step recursively on the two smaller halves until the partition size is 1, resulting in a fully sorted sequence.

Complexity

Best time
O(n log² n)
Average time
O(n log² n)
Worst time
O(n log² n)
Extra space
O(log² n)
Stable
No
In-place
Yes
Because comparison paths are fixed and independent of the input data, Bitonic Sort is a **non-adaptive** sorting network. On parallel systems with \(n\) processors, it runs in **\(O(\log² n)\)** steps.

Interactive visualization

Pseudocode

procedure bitonicSort(A, low, cnt, dir):
  if cnt > 1:
    k ← cnt / 2
    bitonicSort(A, low, k, true)       # Sort ascending
    bitonicSort(A, low + k, k, false)  # Sort descending
    bitonicMerge(A, low, cnt, dir)

procedure bitonicMerge(A, low, cnt, dir):
  if cnt > 1:
    k ← cnt / 2
    for i from low to low + k - 1:
      if dir == (A[i] > A[i + k]):
        swap A[i], A[i + k]
    bitonicMerge(A, low, k, dir)
    bitonicMerge(A, low + k, k, dir)

JavaScript implementation

function bitonicSort(arr) {
  const n = arr.length;
  
  function bitonicMerge(low, cnt, dir) {
    if (cnt > 1) {
      const k = cnt / 2;
      for (let i = low; i < low + k; i++) {
        if (dir === (arr[i] > arr[i + k])) {
          [arr[i], arr[i + k]] = [arr[i + k], arr[i]];
        }
      }
      bitonicMerge(low, k, dir);
      bitonicMerge(low + k, k, dir);
    }
  }
  
  function bitonicSortUtil(low, cnt, dir) {
    if (cnt > 1) {
      const k = cnt / 2;
      bitonicSortUtil(low, k, true);
      bitonicSortUtil(low + k, k, false);
      bitonicMerge(low, cnt, dir);
    }
  }
  
  bitonicSortUtil(0, n, true);
  return arr;
}

Pros and cons

Pros

  • Extremely parallelizable, forming fixed network routes.
  • Highly optimized for GPU execution (CUDA/OpenCL) and custom hardware ASICs.
  • In-place: requires very little recursive overhead.

Cons

  • Only works directly when the array size \(n\) is a power of 2.
  • Worst, average, and best-case complexities are all \(O(n \log² n)\).
  • Slow when executed sequentially on standard single-core CPUs.
  • Unstable sorting order.

When (not) to use it

  • Graphics card & FPGA hardware: Ideal for hardware pipelines, vertex shaders, and parallel processing clusters where sorting networks can run concurrently.
  • Standard CPU sorting: Avoid on general-purpose computers; Quicksort or Mergesort are significantly faster because they have higher cache locality and fewer comparison stages.
Up next: Odd-Even Merge Sort — another parallel sorting network by Ken Batcher that recursively merges sorted halves using odd and even indices.
Share:
Share on X
Share on LinkedIn
Share on Facebook
Share on Reddit
Share on WhatsApp
Share on Telegram
Copy link

Related reading

Bitonic Sort Sorting Algorithm & Guide | Draftsbook · Draftsbook