Home Python C Language C ++ HTML 5 CSS Javascript Java Kotlin SQL DJango Bootstrap React.js R C# PHP ASP.Net Numpy Dart Pandas Digital Marketing

Divide and Conquer



Data Structures and Algorithms (DSA) in C++: Divide and Conquer

Divide and conquer is a powerful algorithmic paradigm used to solve complex problems by breaking them down into smaller, more manageable subproblems. Each subproblem is solved independently, and their solutions are combined to form the final solution. This approach is particularly effective for problems that can be recursively divided into smaller subproblems of the same type.

The divide and conquer strategy involves three main steps:

  1. Divide: Break the problem into smaller subproblems.
  2. Conquer: Recursively solve each subproblem.
  3. Combine: Merge the solutions of the subproblems to solve the original problem.

Key Divide and Conquer Algorithms

Some classic examples of divide and conquer algorithms include:

  1. Merge Sort
  2. Quick Sort
  3. Binary Search
  4. Karatsuba Multiplication
  5. Matrix Multiplication (Strassen's algorithm)

Example 1: Merge Sort

Merge Sort is a classic example of the divide and conquer approach. It divides the array into two halves, recursively sorts each half, and then merges the two sorted halves to produce the sorted array.



        #include 
          #include 
          
          void merge(std::vector& arr, int left, int mid, int right) {
              int n1 = mid - left + 1;
              int n2 = right - mid;
          
              std::vector L(n1), R(n2);
          
              for (int i = 0; i < n1; ++i)
                  L[i] = arr[left + i];
              for (int i = 0; i < n2; ++i)
                  R[i] = arr[mid + 1 + i];
          
              int i = 0, j = 0, k = left;
          
              while (i < n1 && j < n2) {
                  if (L[i] <= R[j]) {
                      arr[k] = L[i];
                      ++i;
                  } else {
                      arr[k] = R[j];
                      ++j;
                  }
                  ++k;
              }
          
              while (i < n1) {
                  arr[k] = L[i];
                  ++i;
                  ++k;
              }
          
              while (j < n2) {
                  arr[k] = R[j];
                  ++j;
                  ++k;
              }
          }
          
          void mergeSort(std::vector& arr, int left, int right) {
              if (left < right) {
                  int mid = left + (right - left) / 2;
          
                  mergeSort(arr, left, mid);
                  mergeSort(arr, mid + 1, right);
          
                  merge(arr, left, mid, right);
              }
          }
          
          int main() {
              std::vector arr = {12, 11, 13, 5, 6, 7};
              int arr_size = arr.size();
          
              std::cout << "Given array is \n";
              for (int i = 0; i < arr_size; i++)
                  std::cout << arr[i] << " ";
              std::cout << std::endl;
          
              mergeSort(arr, 0, arr_size - 1);
          
              std::cout << "\nSorted array is \n";
              for (int i = 0; i < arr_size; i++)
                  std::cout << arr[i] << " ";
              std::cout << std::endl;
              return 0;
          }
      

Example 2: Quick Sort

Quick Sort is another divide and conquer algorithm. It selects a pivot element and partitions the array around the pivot, so that elements less than the pivot are on the left, and elements greater than the pivot are on the right. It then recursively sorts the subarrays.



        #include 
          #include 
          
          int partition(std::vector& arr, int low, int high) {
              int pivot = arr[high];
              int i = (low - 1);
          
              for (int j = low; j <= high - 1; ++j) {
                  if (arr[j] < pivot) {
                      ++i;
                      std::swap(arr[i], arr[j]);
                  }
              }
              std::swap(arr[i + 1], arr[high]);
              return (i + 1);
          }
          
          void quickSort(std::vector& arr, int low, int high) {
              if (low < high) {
                  int pi = partition(arr, low, high);
          
                  quickSort(arr, low, pi - 1);
                  quickSort(arr, pi + 1, high);
              }
          }
          
          int main() {
              std::vector arr = {10, 7, 8, 9, 1, 5};
              int n = arr.size();
          
              std::cout << "Given array is \n";
              for (int i = 0; i < n; i++)
                  std::cout << arr[i] << " ";
              std::cout << std::endl;
          
              quickSort(arr, 0, n - 1);
          
              std::cout << "Sorted array is \n";
              for (int i = 0; i < n; i++)
                  std::cout << arr[i] << " ";
              std::cout << std::endl;
              return 0;
          }
          
      

Example 3: Binary Search

Binary Search is a divide and conquer algorithm used to find an element in a sorted array. It repeatedly divides the array in half, comparing the target value to the middle element.



        #include 
          #include 
          
          int binarySearch(const std::vector& arr, int low, int high, int target) {
              if (high >= low) {
                  int mid = low + (high - low) / 2;
          
                  if (arr[mid] == target)
                      return mid;
                  if (arr[mid] > target)
                      return binarySearch(arr, low, mid - 1, target);
                  return binarySearch(arr, mid + 1, high, target);
              }
          
              return -1;
          }
          
          int main() {
              std::vector arr = {2, 3, 4, 10, 40};
              int target = 10;
              int n = arr.size();
              int result = binarySearch(arr, 0, n - 1, target);
          
              if (result != -1)
                  std::cout << "Element is present at index " << result << std::endl;
              else
                  std::cout << "Element is not present in array" << std::endl;
          
              return 0;
          }
          
      

Example 4: Karatsuba Multiplication

Karatsuba Multiplication is an efficient algorithm for multiplying large integers by breaking them into smaller integers.



        #include 
          #include 
          
          int karatsuba(int x, int y) {
              if (x < 10 || y < 10)
                  return x * y;
          
              int n = std::max(std::to_string(x).size(), std::to_string(y).size());
              int m = n / 2;
          
              int high1 = x / std::pow(10, m);
              int low1 = x % static_cast(std::pow(10, m));
              int high2 = y / std::pow(10, m);
              int low2 = y % static_cast(std::pow(10, m));
          
              int z0 = karatsuba(low1, low2);
              int z1 = karatsuba((low1 + high1), (low2 + high2));
              int z2 = karatsuba(high1, high2);
          
              return (z2 * std::pow(10, 2 * m)) + ((z1 - z2 - z0) * std::pow(10, m)) + z0;
          }
          
          int main() {
              int x = 1234;
              int y = 5678;
          
              std::cout << "Karatsuba multiplication of " << x << " and " << y << " is " << karatsuba(x, y) << std::endl;
              return 0;
          }
          
      




Advertisement





Q3 Schools : India


Online Complier

HTML 5

Python

Zava

C++

C

JavaScript

Website Development

HTML

CSS

JavaScript

Python

SQL

Campus Learning

C

C#

Zava