C++算法与数据结构大全

本文整理了各种算法与数据结构,并给出了C++实现。本文仍在不断更新中,敬请期待。

查找算法

Binary Search

#include 
using namespace std;
int binary_search(int a[], int l, int r, int key)
{
	while (l <= r)
	{
		int m = l + (r - l) / 2;
		if (key == a[m])
			return m;
		else if (key < a[m])
			r = m - 1;
		else
			l = m + 1;
	}
	return -1;
}
int main(int argc, char const *argv[])
{
	int n, key;
	cout << "Enter size of array: ";
	cin >> n;
	cout << "Enter array elements: ";
	int a[n];
	for (int i = 0; i < n; ++i)
	{
		cin >> a[i];
	}
	cout << "Enter search key: ";
	cin >> key;
	int res = binary_search(a, 0, n - 1, key);
	if (res != -1)
		cout << key << " found at index " << res << endl;
	else
		cout << key << " not found" << endl;
	return 0;
}

Interpolation Search

#include 
int InterpolationSearch(int A[], int n, int x)
{
    int low = 0;
    int high = n - 1;
    while (low <= high)
    {
        int mid = low + (((high - 1) * (x - A[low])) / (A[high] - A[low]));
        if (x == A[mid])
            return mid; // Found x, return (exit)
        else if (x < A[mid])
            high = mid - 1; // X lies before mid
        else
            low = mid + 1; // x lies after mid
    }
    return -1;
}

int main()
{
    int A[] = {2, 4, 5, 7, 13, 14, 15, 23};
    int x = 17;
    int index = InterpolationSearch(A, 8, x); // passed array A inside the InterpolationSearch function
    if (index != -1)
        std::cout << "Number " << x << " is at " << index;
    else
        std::cout << "Number " << x << " not found";
}

// randomly set x bcoz array was defined by us , therefore not reasonable for asking input.
// We could have asked for input if array elements were inputed by the user.

Liner Search

#include 
using namespace std;

int LinearSearch(int *array, int size, int key)
{
	for (int i = 0; i < size; ++i)
	{
		if (array[i] == key)
		{
			return i;
		}
	}

	return -1;
}

int main()
{
	int size;
	cout << "\nEnter the size of the Array : ";
	cin >> size;

	int array[size];
	int key;

	//Input array
	cout << "\nEnter the Array of " << size << " numbers : ";
	for (int i = 0; i < size; i++)
	{
		cin >> array[i];
	}

	cout << "\nEnter the number to be searched : ";
	cin >> key;

	int index = LinearSearch(array, size, key);
	if (index != -1)
	{
		cout << "\nNumber found at index : " << index;
	}
	else
	{
		cout << "\nNot found";
	}

	return 0;
}

Exponential Search

#include 
#include 
#include 
using namespaces std;
// Binary Search Algorithm(use by struzik algorithm)
// Time Complexity O(log n) where 'n' is the number of elements
// Worst Time Complexity O(log n)
// Best Time Complexity Ω(1)
// Space Complexity O(1)
// Auxiliary Space Complexity O(1)
template<class Type> inline Type* binary_s(Type *array, size_t size, Type key) {
int32_t lower_index(0), upper_index(size - 1), middle_index;
while (lower_index <= upper_index) {
     middle_index = floor((lower_index + upper_index) / 2);
     if (*(array + middle_index) < key) lower_index = (middle_index + 1);
     else if (*(array + middle_index) > key)upper_index = (middle_index - 1);
     else  return (array + middle_index);
     }
return nullptr;
}
// Struzik Search Algorithm(Exponential)
// Time Complexity O(log i)where i is the position of search key in the list
// Worst Time Complexity O(log i)
// Best Time Complexity Ω(1)
// Space Complexity O(1)
// Auxiliary Space Complexity O(1)
/* Tha algorithm try to search the range where the key should be.
If it has been found we do a binary search there.
The range of the search grows by exponential every time.
If the key is larger than the last element of array,
the start of block(block_front) will be equal to the end of block(block_size)
and the algorithm return null ponter,
every other cases the algoritm return fom the loop. */
template<class Type> Type* struzik_search(Type* array, size_t size, Type key) {
  uint32_t block_front(0), block_size = size == 0 ? 0 : 1;
  while (block_front != block_size) {
        if (*(array + block_size - 1) < key) {
           block_front = block_size;
           (block_size * 2 - 1 < size) ? (block_size *= 2) : block_size = size;
           continue;
        }
  return binary_s<Type>(array + block_front, (block_size - block_front), key);
  }
return nullptr;
}
int main() {
// TEST CASES
int *sorted_array = new int[7]{7, 10, 15, 23, 70, 105, 203};
assert(struzik_search<int>(sorted_array, 7, 0) == nullptr);
assert(struzik_search<int>(sorted_array, 7, 1000) == nullptr);
assert(struzik_search<int>(sorted_array, 7, 50) == nullptr);
assert(struzik_search<int>(sorted_array, 7, 7) == sorted_array);
// TEST CASES
return 0;
}

Hash Search

#include 
#include
#define MAX 6  // Determines how much data
#define HASHMAX 5  // Determines the length of the hash table
/**
  * Hash Search Algorithm
  * Best Time Complexity Ω(1)
  * In this algorithm, we use the method of division and reservation remainder to construct the hash function, 
  * and use the method of chain address to solve the conflict, that is, we link a chain list after the data, 
  * and store all the records whose keywords are synonyms in the same linear chain list. */
int data[MAX] = { 1, 10, 15, 5, 8, 7};  // test data
typedef struct list {
    int key;
    struct list * next;
}
node, * link;
node hashtab[HASHMAX];
int counter = 1;
/* int h(int key)
 * Mode of hash detection :
 * Division method */
int h(int key) {
    return key % HASHMAX;
}
/* void create_list(int key)
 * The same after the remainder will be added after the same hash header
 * To avoid conflict, zipper method is used
 * Insert elements into the linked list in the header */
void create_list(int key) {  // Construct hash table
    link p, n;
    int index;
    n = (link) malloc(sizeof(node));
    n -> key = key;
    n -> next = NULL;
    index = h(key);
    p = hashtab[index].next;
    if (p != NULL) {
        n -> next = p;
        hashtab[index].next = n;
    } else {
        hashtab[index].next = n; }
}
/* int hash_search(int key)
 * Input the key to be searched, and get the hash header position through the H (int key) function,
 * then one-dimensional linear search.
 * If found @return element depth and number of searches
 * If not found @return -1 */
int hash_search(int key) {  // Hash lookup function
    link pointer;
    int index;
    counter = 0;
    index = h(key);
    pointer = hashtab[index].next;
    printf("data[%d]:", index);
    while (pointer != NULL) {
        counter++;
        printf("data[%d]:", pointer -> key);
        if (pointer -> key == key)
            return 1;
        else
            pointer = pointer -> next;
    }
    return 0;
}
int main() {
    link p;
    int key, index, i;  // Key is the value to be found
    index = 0;
    // You can write the input mode here
    while (index < MAX) {  // Construct hash table
        create_list(data[index]);
        index++;
    }
    for (i = 0; i < HASHMAX; i++) {  // Output hash table
        printf("hashtab [%d]", i);
        printf("\n");
        p = hashtab[i].next;
        while (p != NULL) {
            printf("please int key:");
            if (p -> key > 0)
                printf("[%d]", p -> key);
            p = p -> next;
        }
        printf("\n");
    }
    while (key != -1) {
        // You can write the input mode here
        // test key = 10
        key = 10;
        if (hash_search(key))
            printf("search time = %d\n", counter);
        else
            printf("no found!\n");
        key = -1;  // Exit test
        /* The test sample is returned as: data[0]:data[5]:data[15]:data[10]:search time = 3
         * The search is successful. There are 10 in this set of data */
    }
    return 0;
}

Median Search

#include
#include
#include
#include
#include
#include
#include
using namespace std;
vector<int>v;
vector<int>s1;
vector<int>s2;
vector<int>s3;
template <class X>
void comp(X x)
{
    if(s1.size()>=x && s1.size()+s2.size()<x)
    {
        cout<<s2[0]<<" is the "<<x+1<<"th element from front";
    }
    else if(s1.size()>x)
    {
        sort(s1.begin(),s1.end());
        cout<<s1[x]<<" is the "<<x+1<<"th element from front";
    }
    else if(s1.size()+s2.size()<=x && s3.size()>x)
    {
        sort(s3.begin(),s3.end());
        cout<<s3[x-s1.size()-s2.size()]<<" is the "<<x+1<<"th element from front";
    }
    else
    {
        cout<<x+1<<" is invalid location";
    }
}
int main()
{
    for(int i=0;i<1000;i++)
    {
        v.push_back(rand()%1000);
    }
    for(int r:v)
    {
        cout<<r<<" ";
    }
    int median=rand()%1000;
    cout<<"\nmedian="<<median<<endl;
    int avg1,avg2,avg3,sum1=0,sum2=0,sum3=0;
    for(int i=0;i<1000;i++)
    {
        if(v.back()==v[median])
        {
            avg1=sum1+v.back();
            s2.push_back(v.back());
        }
        else if(v.back()<v[median])
        {
            avg2=sum2+v.back();
            s1.push_back(v.back());
        }
        else
        {
            avg3=sum3+v.back();
            s3.push_back(v.back());
        }
        v.pop_back();
    }
    int x;
    cout<<"enter the no. to be searched form begining:- ";
    cin>>x;
    comp(x-1);
    return 0;
}

Search

#include 
#include 
#include 

using namespace std;
char paragraph;

int main()
{
    string paragraph;
    cout << "Please enter your paragraph: \n";
    getline(cin, paragraph);
    cout << "\nHello, your paragraph is:\n " << paragraph << "!\n";
    cout << "\nThe size of your paragraph = " << paragraph.size() << " characters. \n\n";

    if (paragraph.empty())
    {
        cout << "\nThe paragraph is empty" << endl;
    }
    else
    {
        while (true)
        {
            string word;
            cout << "Please enter the word you are searching for: ";
            getline(cin, word);
            cout << "Hello, your word is " << word << "!\n";
            if (paragraph.find(word) == string::npos)
            {
                cout << word << " does not exist in the sentence" << endl;
            }
            else
            {
                cout << "The word " << word << " is now found at location " << paragraph.find(word) << endl
                     << endl;
            }
            system("pause");
        }
    }
}

Ternary Search

/*
 * This is a divide and conquer algorithm.
 * It does this by dividing the search space by 3 parts and
 * using its property (usually monotonic property) to find
 * the desired index.
 * 
 * Time Complexity : O(log3 n)
 * Space Complexity : O(1) (without the array)
 */

#include 
using namespace std;

/*
 * The absolutePrecision can be modified to fit preference but 
 * it is recommended to not go lower than 10 due to errors that
 * may occur.
 *
 * The value of _target should be decided or can be decided later
 * by using the variable of the function.
 */

#define _target 10
#define absolutePrecision 10
#define MAX 10000000

int N = 21;
int A[MAX] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 10};

/*
 * get_input function is to receive input from standard IO
 */
void get_input()
{
  // TODO: Get input from STDIO or write input to memory as done above.
}

/*
 * This is the iterative method of the ternary search which returns the index of the element.
 */
int it_ternary_search(int left, int right, int A[], int target)
{
  while (1)
  {
    if (left < right)
    {
      if (right - left < absolutePrecision)
      {
        for (int i = left; i <= right; i++)
          if (A[i] == target)
            return i;

        return -1;
      }

      int oneThird = (left + right) / 3 + 1;
      int twoThird = (left + right) * 2 / 3 + 1;

      if (A[oneThird] == target)
        return oneThird;
      else if (A[twoThird] == target)
        return twoThird;

      else if (target > A[twoThird])
        left = twoThird + 1;
      else if (target < A[oneThird])
        right = oneThird - 1;

      else
        left = oneThird + 1, right = twoThird - 1;
    }
    else
      return -1;
  }
}

/* 
 * This is the recursive method of the ternary search which returns the index of the element.
 */
int rec_ternary_search(int left, int right, int A[], int target)
{
  if (left < right)
  {
    if (right - left < absolutePrecision)
    {
      for (int i = left; i <= right; i++)
        if (A[i] == target)
          return i;

      return -1;
    }

    int oneThird = (left + right) / 3 + 1;
    int twoThird = (left + right) * 2 / 3 + 1;

    if (A[oneThird] == target)
      return oneThird;
    if (A[twoThird] == target)
      return twoThird;

    if (target < A[oneThird])
      return rec_ternary_search(left, oneThird - 1, A, target);
    if (target > A[twoThird])
      return rec_ternary_search(twoThird + 1, right, A, target);

    return rec_ternary_search(oneThird + 1, twoThird - 1, A, target);
  }
  else
    return -1;
}

/*
 * ternary_search is a template function
 * You could either use it_ternary_search or rec_ternary_search according to preference.
 */
void ternary_search(int N, int A[], int target)
{
  cout << it_ternary_search(0, N - 1, A, target) << '\t';
  cout << rec_ternary_search(0, N - 1, A, target) << '\t';
  cout << '\n';
}

int main()
{
  get_input();
  ternary_search(N, A, _target);
  return 0;
}

排序算法

BeadSort

// C++ program to implement gravity/bead sort 
#include 
#include 
using namespace std; 
  
#define BEAD(i, j) beads[i * max + j] 
  
// function to perform the above algorithm 
void beadSort(int *a, int len) 
{ 
    // Find the maximum element 
    int max = a[0]; 
    for (int i = 1; i < len; i++) 
        if (a[i] > max) 
           max = a[i]; 
  
    // allocating memory 
    unsigned char beads[max*len]; 
    memset(beads, 0, sizeof(beads)); 
  
    // mark the beads 
    for (int i = 0; i < len; i++) 
        for (int j = 0; j < a[i]; j++) 
            BEAD(i, j) = 1; 
  
    for (int j = 0; j < max; j++) 
    { 
        // count how many beads are on each post 
        int sum = 0; 
        for (int i=0; i < len; i++) 
        { 
            sum += BEAD(i, j); 
            BEAD(i, j) = 0; 
        } 
  
        // Move beads down 
        for (int i = len - sum; i < len; i++) 
            BEAD(i, j) = 1; 
    } 
  
    // Put sorted values in array using beads 
    for (int i = 0; i < len; i++) 
    { 
        int j; 
        for (j = 0; j < max && BEAD(i, j); j++); 
  
        a[i] = j; 
    } 
} 
  
// driver function to test the algorithm 
int main() 
{ 
    int a[] = {5, 3, 1, 7, 4, 1, 1, 20}; 
    int len = sizeof(a)/sizeof(a[0]); 
  
    beadSort(a, len); 
  
    for (int i = 0; i < len; i++) 
        printf("%d ", a[i]); 
  
    return 0; 
} 

BitonicSort

/* C++ Program for Bitonic Sort. Note that this program 
   works only when size of input is a power of 2. */

#include 
#include 
using namespace std;

/*The parameter dir indicates the sorting direction, ASCENDING 
   or DESCENDING; if (a[i] > a[j]) agrees with the direction, 
   then a[i] and a[j] are interchanged.*/
void compAndSwap(int a[], int i, int j, int dir)
{
    if (dir == (a[i] > a[j]))
        swap(a[i], a[j]);
}

/*It recursively sorts a bitonic sequence in ascending order, 
  if dir = 1, and in descending order otherwise (means dir=0). 
  The sequence to be sorted starts at index position low, 
  the parameter cnt is the number of elements to be sorted.*/
void bitonicMerge(int a[], int low, int cnt, int dir)
{
    if (cnt > 1)
    {
        int k = cnt / 2;
        for (int i = low; i < low + k; i++)
            compAndSwap(a, i, i + k, dir);
        bitonicMerge(a, low, k, dir);
        bitonicMerge(a, low + k, k, dir);
    }
}

/* This function first produces a bitonic sequence by recursively 
    sorting its two halves in opposite sorting orders, and then 
    calls bitonicMerge to make them in the same order */
void bitonicSort(int a[], int low, int cnt, int dir)
{
    if (cnt > 1)
    {
        int k = cnt / 2;

        // sort in ascending order since dir here is 1
        bitonicSort(a, low, k, 1);

        // sort in descending order since dir here is 0
        bitonicSort(a, low + k, k, 0);

        // Will merge wole sequence in ascending order
        // since dir=1.
        bitonicMerge(a, low, cnt, dir);
    }
}

/* Caller of bitonicSort for sorting the entire array of 
   length N in ASCENDING order */
void sort(int a[], int N, int up)
{
    bitonicSort(a, 0, N, up);
}

// Driver code
int main()
{
    int a[] = {3, 7, 4, 8, 6, 2, 1, 5};
    int N = sizeof(a) / sizeof(a[0]);

    int up = 1; // means sort in ascending order
    sort(a, N, up);

    printf("Sorted array: \n");
    for (int i = 0; i < N; i++)
        printf("%d ", a[i]);
    return 0;
}

BubbleSort

//Bubble Sort

#include 
#include 
using namespace std;

int main()
{
	int n;
	short swap_check = 1;
	cout << "Enter the amount of numbers to sort: ";
	cin >> n;
	vector<int> numbers;
	cout << "Enter " << n << " numbers: ";
	int num;

	//Input
	for (int i = 0; i < n; i++)
	{
		cin >> num;
		numbers.push_back(num);
	}

	//Bubble Sorting
	for (int i = 0; (i < n) && (swap_check == 1); i++)
	{
		swap_check = 0;
		for (int j = 0; j < n - 1 - i; j++)
		{
			if (numbers[j] > numbers[j + 1])
			{
				swap_check = 1;
				swap(numbers[j], numbers[j + 1]);// by changing swap location. I mean, j. If the number is greater than j + 1, then it means the location.
			}
		}
	}

	//Output
	cout << "\nSorted Array : ";
	for (int i = 0; i < numbers.size(); i++)
	{
		if (i != numbers.size() - 1)
		{
			cout << numbers[i] << ", ";
		}
		else
		{
			cout << numbers[i] << endl;
		}
	}
	return 0;
}

CocktailSelectionSort

#include 
using namespace std;

//Iterative Version

void CocktailSelectionSort(vector<int> &vec, int low, int high)
{
  while (low <= high)
  {
    int minimum = vec[low];
    int minimumindex = low;
    int maximum = vec[high];
    int maximumindex = high;

    for (int i = low; i <= high; i++)
    {
      if (vec[i] >= maximum)
      {
        maximum = vec[i];
        maximumindex = i;
      }
      if (vec[i] <= minimum)
      {
        minimum = vec[i];
        minimumindex = i;
      }
    }
    if (low != maximumindex || high != minimumindex)
    {
      swap(vec[low], vec[minimumindex]);
      swap(vec[high], vec[maximumindex]);
    }
    else
    {
      swap(vec[low], vec[high]);
    }

    low++;
    high--;
  }
}

//Recursive Version

void CocktailSelectionSort(vector<int> &vec, int low, int high)
{

  if (low >= high)
    return;

  int minimum = vec[low];
  int minimumindex = low;
  int maximum = vec[high];
  int maximumindex = high;

  for (int i = low; i <= high; i++)
  {
    if (vec[i] >= maximum)
    {
      maximum = vec[i];
      maximumindex = i;
    }
    if (vec[i] <= minimum)
    {
      minimum = vec[i];
      minimumindex = i;
    }
  }
  if (low != maximumindex || high != minimumindex)
  {
    swap(vec[low], vec[minimumindex]);
    swap(vec[high], vec[maximumindex]);
  }
  else
  {
    swap(vec[low], vec[high]);
  }

  CocktailSelectionSort(vec, low + 1, high - 1);
}

//main function, select any one of iterative or recursive version

int main()
{

  int n;
  cout << "Enter number of elements\n";
  cin >> n;
  std::vector<int> v(n);
  cout << "Enter all the elements\n";
  for (int i = 0; i < n; ++i)
  {
    cin >> v[i];
  }

  CocktailSelectionSort(v, 0, n - 1);
  cout << "Sorted elements are\n";
  for (int i = 0; i < n; ++i)
  {
    cout << v[i] << " ";
  }

  return 0;
}

CountingSortString

#include 

using namespace std;

void countSort(string arr)
{

    string output;

    int count[256], i;
    for (int i = 0; i < 256; i++)
        count[i] = 0;

    for (i = 0; arr[i]; ++i)
        ++count[arr[i]];

    for (i = 1; i <= 256; ++i)
        count[i] += count[i - 1];

    for (i = 0; arr[i]; ++i)
    {
        output[count[arr[i]] - 1] = arr[i];
        --count[arr[i]];
    }

    for (i = 0; arr[i]; ++i)
        arr[i] = output[i];

    cout << "Sorted character array is " << arr;
}

int main()
{
    string arr;
    cin >> arr;

    countSort(arr);

    return 0;
}

CountingSort

#include 
using namespace std;

int Max(int Arr[], int N)
{
	int max = Arr[0];
	for (int i = 1; i < N; i++)
		if (Arr[i] > max)
			max = Arr[i];
	return max;
}

int Min(int Arr[], int N)
{
	int min = Arr[0];
	for (int i = 1; i < N; i++)
		if (Arr[i] < min)
			min = Arr[i];
	return min;
}

void Print(int Arr[], int N)
{
	for (int i = 0; i < N; i++)
		cout << Arr[i] << ", ";
}

int *Counting_Sort(int Arr[], int N)
{

	int max = Max(Arr, N);
	int min = Min(Arr, N);
	int *Sorted_Arr = new int[N];

	int *Count = new int[max - min + 1];

	for (int i = 0; i < N; i++)
		Count[Arr[i] - min]++;

	for (int i = 1; i < (max - min + 1); i++)
		Count[i] += Count[i - 1];

	for (int i = N - 1; i >= 0; i--)
	{
		Sorted_Arr[Count[Arr[i] - min] - 1] = Arr[i];
		Count[Arr[i] - min]--;
	}

	return Sorted_Arr;
}

int main()
{

	int Arr[] = {47, 65, 20, 66, 25, 53, 64, 69, 72, 22, 74, 25, 53, 15, 42, 36, 4, 69, 86, 19}, N = 20;
	int *Sorted_Arr;

	cout << "\n\tOrignal Array = ";
	Print(Arr, N);
	Sorted_Arr = Counting_Sort(Arr, N);
	cout << "\n\t Sorted Array = ";
	Print(Sorted_Arr, N);
	cout << endl;

	return 0;
}

InsertionSort

#include 
using namespace std;

int main()
{
	int n;
	cout << "\nEnter the length of your array : ";
	cin >> n;
	int Array[n];
	cout << "\nEnter any " << n << " Numbers for Unsorted Array : ";

	//Input
	for (int i = 0; i < n; i++)
	{
		cin >> Array[i];
	}

	//Sorting
	for (int i = 1; i < n; i++)
	{
		int temp = Array[i];
		int j = i - 1;
		while (j >= 0 && temp < Array[j])
		{
			Array[j + 1] = Array[j];
			j--;
		}
		Array[j + 1] = temp;
	}

	//Output
	cout << "\nSorted Array : ";
	for (int i = 0; i < n; i++)
	{
		cout << Array[i] << "\t";
	}
	return 0;
}

MergeSort

#include 
using namespace std;

void merge(int arr[], int l, int m, int r)
{
    int i, j, k;
    int n1 = m - l + 1;
    int n2 = r - m;

    int L[n1], R[n2];

    for (i = 0; i < n1; i++)
        L[i] = arr[l + i];
    for (j = 0; j < n2; j++)
        R[j] = arr[m + 1 + j];

    i = 0;
    j = 0;
    k = l;
    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(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);
    }
}

void show(int A[], int size)
{
    int i;
    for (i = 0; i < size; i++)
        cout << A[i] << "\n";
}

int main()
{
    int size;
    cout << "\nEnter the number of elements : ";

    cin >> size;

    int arr[size];

    cout << "\nEnter the unsorted elements : ";

    for (int i = 0; i < size; ++i)
    {
        cout << "\n";
        cin >> arr[i];
    }

    mergeSort(arr, 0, size);

    cout << "Sorted array\n";
    show(arr, size);
    return 0;
}

NumericStringSort

#include 
#include 
#include 
using namespace std;

bool NumericSort(string a, string b)
{
  while (a[0] == '0')
  {
    a.erase(a.begin());
  }
  while (b[0] == '0')
  {
    b.erase(b.begin());
  }
  int n = a.length();
  int m = b.length();
  if (n == m)
    return a < b;
  return n < m;
}

int main()
{

  int n;
  cout << "Enter number of elements to be sorted Numerically\n";
  cin >> n;

  vector<string> v(n);
  cout << "Enter the string of Numbers\n";
  for (int i = 0; i < n; i++)
  {
    cin >> v[i];
  }

  sort(v.begin(), v.end());
  cout << "Elements sorted normally \n";
  for (int i = 0; i < n; i++)
  {
    cout << v[i] << " ";
  }
  cout << "\n";

  sort(v.begin(), v.end(), NumericSort);
  cout << "Elements sorted Numerically \n";
  for (int i = 0; i < n; i++)
  {
    cout << v[i] << " ";
  }

  return 0;
}

OddEvenSort

#include 
#include 

using namespace std;

void oddEven(vector<int> &arr, int size)
{
	bool sorted = false;
	while (!sorted)
	{
		sorted = true;
		for (int i = 1; i < size - 1; i += 2) //Odd
		{
			if (arr[i] > arr[i + 1])
			{
				swap(arr[i], arr[i + 1]);
				sorted = false;
			}
		}

		for (int i = 0; i < size - 1; i += 2) //Even
		{
			if (arr[i] > arr[i + 1])
			{
				swap(arr[i], arr[i + 1]);
				sorted = false;
			}
		}
	}
}

void show(vector<int> A, int size)
{
	int i;
	for (i = 0; i < size; i++)
		cout << A[i] << "\n";
}

int main()
{
	int size, temp;
	cout << "\nEnter the number of elements : ";
	cin >> size;

	vector<int> arr;

	cout << "\nEnter the unsorted elements : \n";

	for (int i = 0; i < size; ++i)
	{
		cin >> temp;
		arr.push_back(temp);
	}

	oddEven(arr, size);

	cout << "Sorted array\n";
	show(arr, size);
	return 0;
}

QuickSort

#include 
using namespace std;

int partition(int arr[], int low, int high)
{
    int pivot = arr[high]; // pivot
    int i = (low - 1);     // Index of smaller element

    for (int j = low; j < high; j++)
    {
        // If current element is smaller than or
        // equal to pivot
        if (arr[j] <= pivot)
        {
            i++; // increment index of smaller element
            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);
}

void quickSort(int arr[], int low, int high)
{
    if (low < high)
    {

        int p = partition(arr, low, high);

        quickSort(arr, low, p - 1);
        quickSort(arr, p + 1, high);
    }
}

void show(int arr[], int size)
{
    for (int i = 0; i < size; i++)
        cout << arr[i] << "\n";
}

// Driver program to test above functions
int main()
{
    int size;
    cout << "\nEnter the number of elements : ";

    cin >> size;

    int arr[size];

    cout << "\nEnter the unsorted elements : ";

    for (int i = 0; i < size; ++i)
    {
        cout << "\n";
        cin >> arr[i];
    }
    quickSort(arr, 0, size);
    cout << "Sorted array\n";
    show(arr, size);
    return 0;
}

RadixSort

#include 
#include 
#include 
#include 
using namespace std;
void radixsort(int a[], int n)
{
	int count[10];
	int output[n];
	memset(output, 0, sizeof(output));
	memset(count, 0, sizeof(count));
	int max = 0;
	for (int i = 0; i < n; ++i)
	{
		if (a[i] > max)
		{
			max = a[i];
		}
	}
	int maxdigits = 0;
	while (max)
	{
		maxdigits++;
		max /= 10;
	}
	for (int j = 0; j < maxdigits; j++)
	{
		for (int i = 0; i < n; i++)
		{
			int t = pow(10, j);
			count[(a[i] % (10 * t)) / t]++;
		}
		int k = 0;
		for (int p = 0; p < 10; p++)
		{
			for (int i = 0; i < n; i++)
			{
				int t = pow(10, j);
				if ((a[i] % (10 * t)) / t == p)
				{
					output[k] = a[i];
					k++;
				}
			}
		}
		memset(count, 0, sizeof(count));
		for (int i = 0; i < n; ++i)
		{
			a[i] = output[i];
		}
	}
}
void print(int a[], int n)
{
	for (int i = 0; i < n; ++i)
	{
		cout << a[i] << " ";
	}
	cout << endl;
}
int main(int argc, char const *argv[])
{
	int a[] = {170, 45, 75, 90, 802, 24, 2, 66};
	int n = sizeof(a) / sizeof(a[0]);
	radixsort(a, n);
	print(a, n);
	return 0;
}

SelectionSort

#include 
using namespace std;

int main()
{
	int Array[6];
	cout << "\nEnter any 6 Numbers for Unsorted Array : ";

	//Input
	for (int i = 0; i < 6; i++)
	{
		cin >> Array[i];
	}

	//Selection Sorting
	for (int i = 0; i < 6; i++)
	{
		int min = i;
		for (int j = i + 1; j < 6; j++)
		{
			if (Array[j] < Array[min])
			{
				min = j; //Finding the smallest number in Array
			}
		}
		int temp = Array[i];
		Array[i] = Array[min];
		Array[min] = temp;
	}

	//Output
	cout << "\nSorted Array : ";
	for (int i = 0; i < 6; i++)
	{
		cout << Array[i] << "\t";
	}
}

ShellSort

#include 
using namespace std;

int main()
{
	int size = 10;
	int array[size];
	// Input
	cout << "\nHow many numbers do want to enter in unsorted array : ";
	cin >> size;
	cout << "\nEnter the numbers for unsorted array : ";
	for (int i = 0; i < size; i++)
	{
		cin >> array[i];
	}

	// Sorting
	for (int i = size / 2; i > 0; i = i / 2)
	{
		for (int j = i; j < size; j++)
		{
			for (int k = j - i; k >= 0; k = k - i)
			{
				if (array[k] < array[k + i])
				{
					break;
				}
				else
				{
					int temp = array[k + i];
					array[k + i] = array[k];
					array[k] = temp;
				}
			}
		}
	}

	// Output
	cout << "\nSorted array : ";
	for (int i = 0; i < size; ++i)
	{
		cout << array[i] << "\t";
	}
	return 0;
}

SlowSort

#include 
using namespace std;

void SlowSort(int a[], int i, int j)
{
  if (i >= j)
    return;
  int m = i + (j - i) / 2; //midpoint, implemented this way to avoid overflow
  int temp;
  SlowSort(a, i, m);
  SlowSort(a, m + 1, j);
  if (a[j] < a[m])
  {
    temp = a[j]; //swapping a[j] & a[m]
    a[j] = a[m];
    a[m] = temp;
  }
  SlowSort(a, i, j - 1);
}

//Sample Main function

int main()
{
  int size;
  cout << "\nEnter the number of elements : ";

  cin >> size;

  int arr[size];

  cout << "\nEnter the unsorted elements : ";

  for (int i = 0; i < size; ++i)
  {
    cout << "\n";
    cin >> arr[i];
  }

  SlowSort(arr, 0, size);

  cout << "Sorted array\n";

  for (int i = 0; i < size; ++i)
  {
    cout << arr[i] << " ";
  }
  return 0;
}

TimSort

#include 
using namespace std;
const int RUN = 32;
 
// this function sorts array from left index to to right index which is of size atmost RUN
void insertionSort(int arr[], int left, int right)
{
    for (int i = left + 1; i <= right; i++)
    {
        int temp = arr[i];
        int j = i - 1;
        while (arr[j] > temp && j >= left)
        {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = temp;
    }
}
 
// merge function merges the sorted runs
void merge(int arr[], int l, int m, int r)
{
    // original array is broken in two parts, left and right array
    int len1 = m - l + 1, len2 = r - m;
    int left[len1], right[len2];
    for (int i = 0; i < len1; i++)
        left[i] = arr[l + i];
    for (int i = 0; i < len2; i++)
        right[i] = arr[m + 1 + i];
 
    int i = 0;
    int j = 0;
    int k = l;
 
    // after comparing, we merge those two array in larger sub array
    while (i < len1 && j < len2)
    {
        if (left[i] <= right[j])
        {
            arr[k] = left[i];
            i++;
        }
        else
        {
            arr[k] = right[j];
            j++;
        }
        k++;
    }
 
    // copy remaining elements of left, if any
    while (i < len1)
    {
        arr[k] = left[i];
        k++;
        i++;
    }
 
    // copy remaining element of right, if any
    while (j < len2)
    {
        arr[k] = right[j];
        k++;
        j++;
    }
}
 
// iterative Timsort function to sort the array[0...n-1] (similar to merge sort)
void timSort(int arr[], int n)
{
    // Sort individual subarrays of size RUN
    for (int i = 0; i < n; i+=RUN)
        insertionSort(arr, i, min((i+31), (n-1)));
 
    // start merging from size RUN (or 32). It will merge to form size 64, then 128, 256 and so on ....
    for (int size = RUN; size < n; size = 2*size)
    {
        // pick starting point of left sub array. We are going to merge arr[left..left+size-1] and arr[left+size, left+2*size-1]
        // After every merge, we increase left by 2*size
        for (int left = 0; left < n; left += 2*size)
        {
            // find ending point of left sub array
            // mid+1 is starting point of right sub array
            int mid = left + size - 1;
            int right = min((left + 2*size - 1), (n-1));
 
            // merge sub array arr[left.....mid] & arr[mid+1....right]
            merge(arr, left, mid, right);
        }
    }
}
 
// utility function to print the Array
void printArray(int arr[], int n)
{
    for (int i = 0; i < n; i++)
        printf("%d  ", arr[i]);
    printf("\n");
}
 
// Driver program to test above function
int main()
{
    int arr[] = {5, 21, 7, 23, 19};
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Given Array is\n");
    printArray(arr, n);
 
    timSort(arr, n);
 
    printf("After Sorting Array is\n");
    printArray(arr, n);
    return 0;
}

BucketSort

#include 
#include 
#include 
using namespace std;

// Function to sort arr[] of size n using bucket sort
void bucketSort(float arr[], int n)
{
   // 1) Create n empty buckets
   vector<float> b[n];

   // 2) Put array elements in different buckets
   for (int i = 0; i < n; i++)
   {
      int bi = n * arr[i]; // Index in bucket
      b[bi].push_back(arr[i]);
   }

   // 3) Sort individual buckets
   for (int i = 0; i < n; i++)
      sort(b[i].begin(), b[i].end());

   // 4) Concatenate all buckets into arr[]
   int index = 0;
   for (int i = 0; i < n; i++)
      for (int j = 0; j < b[i].size(); j++)
         arr[index++] = b[i][j];
}

/* Driver program to test above funtion */
int main()
{
   float arr[] = {0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434};
   int n = sizeof(arr) / sizeof(arr[0]);
   bucketSort(arr, n);

   cout << "Sorted array is \n";
   for (int i = 0; i < n; i++)
      cout << arr[i] << " ";
   return 0;
}

CombSort

#include 

using namespace std;

int a[100005];
int n;

int FindNextGap(int x)
{
    x = (x * 10) / 13;

    return max(1, x);
}

void CombSort(int a[], int l, int r)
{
    //Init gap
    int gap = n;

    //Initialize swapped as true to make sure that loop runs
    bool swapped = true;

    //Keep running until gap = 1 or none elements were swapped
    while (gap != 1 || swapped)
    {
        //Find next gap
        gap = FindNextGap(gap);

        swapped = false;

        // Compare all elements with current gap
        for (int i = l; i <= r - gap; ++i)
        {
            if (a[i] > a[i + gap])
            {
                swap(a[i], a[i + gap]);
                swapped = true;
            }
        }
    }
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];

    CombSort(a, 1, n);

    for (int i = 1; i <= n; ++i)
        cout << a[i] << ' ';
    return 0;
}

HeapSort

#include 
#include 

void heapify(int *a, int i, int n) {
    int largest = i;
    const int l = 2 * i + 1;
    const int r = 2 * i + 2;

    if (l < n && a[l] > a[largest])
        largest = l;

    if (r < n && a[r] > a[largest])
        largest = r;

    if (largest != i) {
        std::swap(a[i], a[largest]);
        heapify(a, n, largest);
    }
}

void heapsort(int *a, int n) {
    for (int i = n - 1; i >= 0; --i) {
        std::swap(a[0], a[i]);
        heapify(a, 0, i);
    }
}

void build_maxheap(int *a, int n) {
    for (int i = n / 2 - 1; i >= 0; --i) {
        heapify(a, i, n);
    }
}

int main() {
    int n;
    std::cout << "Enter number of elements of array\n";
    std::cin >> n;
    int a[20];
    for (int i = 0; i < n; ++i) {
        std::cout << "Enter Element " << i << std::endl;
        std::cin >> a[i];
    }

    build_maxheap(a, n);
    heapsort(a, n);
    std::cout << "Sorted Output\n";
    for (int i = 0; i < n; ++i) {
        std::cout << a[i] << std::endl;
    }

    std::getchar();
}

LibrarySort

#include 
#include 

void librarySort(int *index, int n) {
    int lib_size, index_pos,
        *gaps,        // gaps
        *library[2];  // libraries

    bool target_lib, *numbered;

    for (int i = 0; i < 2; i++)
        library[i] = new int[n];

    gaps = new int[n + 1];
    numbered = new bool[n + 1];

    lib_size = 1;
    index_pos = 1;
    target_lib = 0;
    library[target_lib][0] = index[0];

    while (index_pos < n) {
        // binary search
        int insert = std::distance(
            library[target_lib],
            std::lower_bound(library[target_lib],
                             library[target_lib] + lib_size, index[index_pos]));

        // if there is no gap to insert a new index ...

        if (numbered[insert] == true) {
            int prov_size = 0, next_target_lib = !target_lib;

            // update library and clear gaps

            for (int i = 0; i <= n; i++) {
                if (numbered[i] == true) {
                    library[next_target_lib][prov_size] = gaps[i];
                    prov_size++;
                    numbered[i] = false;
                }

                if (i <= lib_size) {
                    library[next_target_lib][prov_size] =
                        library[target_lib][i];
                    prov_size++;
                }
            }

            target_lib = next_target_lib;
            lib_size = prov_size - 1;
        } else {
            numbered[insert] = true;
            gaps[insert] = index[index_pos];
            index_pos++;
        }
    }

    int index_pos_for_output = 0;
    for (int i = 0; index_pos_for_output < n; i++) {
        if (numbered[i] == true) {
            // std::cout << gaps[i] << std::endl;
            index[index_pos_for_output] = gaps[i];
            index_pos_for_output++;
        }

        if (i < lib_size) {
            // std::cout << library[target_lib][i] << std::endl;
            index[index_pos_for_output] = library[target_lib][i];
            index_pos_for_output++;
        }
    }
}

int main() {
    // ---example--
    int index_ex[] = {-6, 5, 9, 1, 9, 1, 0, 1, -8, 4, -12};
    int n_ex = sizeof(index_ex) / sizeof(index_ex[0]);

    librarySort(index_ex, n_ex);
    std::cout << "sorted array :" << std::endl;
    for (int i = 0; i < n_ex; i++)
        std::cout << index_ex[i] << " ";
    std::cout << std::endl;

    /* --output--
    sorted array :
    -12 -8 -6 0 1 1 1 4 5 9 9
    */
}

回溯算法

Graph Coloring

#include 

// Number of vertices in the graph
#define V 4

void printSolution(int color[]);

/* A utility function to check if the current color assignment
   is safe for vertex v */
bool isSafe(int v, bool graph[V][V], int color[], int c)
{
    for (int i = 0; i < V; i++)
        if (graph[v][i] && c == color[i])
            return false;
    return true;
}

/* A recursive utility function to solve m coloring problem */
void graphColoring(bool graph[V][V], int m, int color[], int v)
{
    /* base case: If all vertices are assigned a color then
       return true */
    if (v == V)
    {
        printSolution(color);
        return;
    }

    /* Consider this vertex v and try different colors */
    for (int c = 1; c <= m; c++)
    {
        /* Check if assignment of color c to v is fine*/
        if (isSafe(v, graph, color, c))
        {
            color[v] = c;

            /* recur to assign colors to rest of the vertices */
            graphColoring(graph, m, color, v + 1);

            /* If assigning color c doesn't lead to a solution
               then remove it */
            color[v] = 0;
        }
    }
}

/* A utility function to print solution */
void printSolution(int color[])
{
    printf(" Following are the assigned colors \n");
    for (int i = 0; i < V; i++)
        printf(" %d ", color[i]);
    printf("\n");
}

// driver program to test above function
int main()
{
    /* Create following graph and test whether it is 3 colorable
      (3)---(2)
       |   / |
       |  /  |
       | /   |
      (0)---(1)
    */
    bool graph[V][V] = {
        {0, 1, 1, 1},
        {1, 0, 1, 0},
        {1, 1, 0, 1},
        {1, 0, 1, 0},
    };
    int m = 3; // Number of colors

    int color[V];

    for (int i = 0; i < V; i++)
        color[i] = 0;

    graphColoring(graph, m, color, 0);
    return 0;
}

Knight Tour

#include 
#define n 8

/**
A knight's tour is a sequence of moves of a knight on a chessboard
such that the knight visits every square only once. If the knight 
ends on a square that is one knight's move from the beginning 
square (so that it could tour the board again immediately, following 
the same path), the tour is closed; otherwise, it is open.
**/

using namespace std;
bool issafe(int x,int y,int sol[n][n])
{
    return (x<n && x>=0 && y<n && y>=0 && sol[x][y]==-1);

}
bool solve(int x,int y, int mov, int sol[n][n], int xmov[n], int ymov[n])
{
    int k,xnext,ynext;

    if(mov == n*n)
        return true;

    for(k=0;k<8;k++)
    {
        xnext=x+xmov[k];
        ynext=y+ymov[k];

        if(issafe(xnext,ynext,sol))
            {
                sol[xnext][ynext]=mov;

                if(solve(xnext,ynext,mov+1,sol,xmov,ymov)==true)
                    return true;
                else
                    sol[xnext][ynext]=-1;
            }
    }
    return false;
}
int main()
{
    //initialize();

    int sol[n][n];
    int i,j;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            sol[i][j]=-1;

    int xmov[8] = {  2, 1, -1, -2, -2, -1,  1,  2 };
    int ymov[8] = {  1, 2,  2,  1, -1, -2, -2, -1 };
    sol[0][0]=0;

    bool flag=solve(0,0,1,sol,xmov,ymov);
    if(flag==false)
        cout<<"solution doesnot exist \n";
    else
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
                cout<<sol[i][j]<<"  ";
            cout<<"\n";
        }
    }
}

Minimax

#include 
#include 
#include 

using std::cout;
using std::endl;
using std::max;
using std::min;
using std::vector;

int minimax(int depth, int node_index, bool is_max, vector<int> scores,
            int height) {
    if (depth == height)
        return scores[node_index];

    int v1 = minimax(depth + 1, node_index * 2, !is_max, scores, height);
    int v2 = minimax(depth + 1, node_index * 2 + 1, !is_max, scores, height);

    return is_max ? max(v1, v2) : min(v1, v2);
}

int main() {
    vector<int> scores = { 90, 23, 6, 33, 21, 65, 123, 34423 };
    int height = log2(scores.size());

    cout << "Optimal value: " << minimax(0, 0, true, scores, height) << endl;
}

N Queens

#include 
#define N 4
using namespace std;

void printSolution(int board[N][N])
{
    cout << "\n";
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
            cout << "" << board[i][j];
        cout << "\n";
    }
}

bool isSafe(int board[N][N], int row, int col)
{
    int i, j;

    /* Check this row on left side */
    for (i = 0; i < col; i++)
        if (board[row][i])
            return false;

    /* Check upper diagonal on left side */
    for (i = row, j = col; i >= 0 && j >= 0; i--, j--)
        if (board[i][j])
            return false;

    /* Check lower diagonal on left side */
    for (i = row, j = col; j >= 0 && i < N; i++, j--)
        if (board[i][j])
            return false;

    return true;
}

void solveNQ(int board[N][N], int col)
{

    if (col >= N)
    {
        printSolution(board);
        return;
    }

    /* Consider this column and try placing
       this queen in all rows one by one */
    for (int i = 0; i < N; i++)
    {
        /* Check if queen can be placed on
          board[i][col] */
        if (isSafe(board, i, col))
        {
            /* Place this queen in board[i][col] */
            //            cout<<"\n"<
            board[i][col] = 1;

            /* recur to place rest of the queens */
            solveNQ(board, col + 1);

            board[i][col] = 0; // BACKTRACK
        }
    }
}

int main()
{

    int board[N][N] = {{0, 0, 0, 0},
                       {0, 0, 0, 0},
                       {0, 0, 0, 0},
                       {0, 0, 0, 0}};

    solveNQ(board, 0);
    return 0;
}

N Queens Print Solution

#include 
#define n 4

void PrintSol(int Board[n][n]) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            std::cout << Board[i][j] << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

bool CanIMove(int Board[n][n], int row, int col) {
    /// check in the row
    for (int i = 0; i < col; i++) {
        if (Board[row][i] == 1)
            return false;
    }
    /// check the first diagonal
    for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
        if (Board[i][j] == 1)
            return false;
    }
    /// check the second diagonal
    for (int i = row, j = col; i <= n - 1 && j >= 0; i++, j--) {
        if (Board[i][j] == 1)
            return false;
    }
    return true;
}

void NQueenSol(int Board[n][n], int col) {
    if (col >= n) {
        PrintSol(Board);
        return;
    }
    for (int i = 0; i < n; i++) {
        if (CanIMove(Board, i, col)) {
            Board[i][col] = 1;
            NQueenSol(Board, col + 1);
            Board[i][col] = 0;
        }
    }
}

int main() {
    int Board[n][n] = {0};
    NQueenSol(Board, 0);
}

Rate Maze

/*
	A Maze is given as N*N binary matrix of blocks where source block is the upper
	left most block i.e., maze[0][0] and destination block is lower rightmost 
	block i.e., maze[N-1][N-1]. A rat starts from source and has to reach destination.
	The rat can move only in two directions: forward and down. In the maze matrix, 
	0 means the block is dead end and 1 means the block can be used in the path 
	from source to destination.
*/
#include 
#define size 4

using namespace std;

int solveMaze(int currposrow, int currposcol, int maze[size][size], int soln[size][size])
{
	if ((currposrow == size - 1) && (currposcol == size - 1))
	{
		soln[currposrow][currposcol] = 1;
		for (int i = 0; i < size; ++i)
		{
			for (int j = 0; j < size; ++j)
			{
				cout << soln[i][j];
			}
			cout << endl;
		}
		return 1;
	}
	else
	{
		soln[currposrow][currposcol] = 1;

		// if there exist a solution by moving one step ahead in a collumn
		if ((currposcol < size - 1) && maze[currposrow][currposcol + 1] == 1 && solveMaze(currposrow, currposcol + 1, maze, soln))
		{
			return 1;
		}

		// if there exists a solution by moving one step ahead in a row
		if ((currposrow < size - 1) && maze[currposrow + 1][currposcol] == 1 && solveMaze(currposrow + 1, currposcol, maze, soln))
		{
			return 1;
		}

		// the backtracking part
		soln[currposrow][currposcol] = 0;
		return 0;
	}
}

int main(int argc, char const *argv[])
{
	int maze[size][size] = {
		{1, 0, 1, 0},
		{1, 0, 1, 1},
		{1, 0, 0, 1},
		{1, 1, 1, 1}};

	int soln[size][size];

	for (int i = 0; i < size; ++i)
	{
		for (int j = 0; j < size; ++j)
		{
			soln[i][j] = 0;
		}
	}

	int currposrow = 0;
	int currposcol = 0;
	solveMaze(currposrow, currposcol, maze, soln);
	return 0;
}

Sudoku Solve

#include 
using namespace std;
///N=9;
int n = 9;

bool isPossible(int mat[][9], int i, int j, int no)
{
    ///Row or col nahin hona chahiye
    for (int x = 0; x < n; x++)
    {
        if (mat[x][j] == no || mat[i][x] == no)
        {
            return false;
        }
    }

    /// Subgrid mein nahi hona chahiye
    int sx = (i / 3) * 3;
    int sy = (j / 3) * 3;

    for (int x = sx; x < sx + 3; x++)
    {
        for (int y = sy; y < sy + 3; y++)
        {
            if (mat[x][y] == no)
            {
                return false;
            }
        }
    }

    return true;
}
void printMat(int mat[][9])
{

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cout << mat[i][j] << " ";
            if ((j + 1) % 3 == 0)
            {
                cout << '\t';
            }
        }
        if ((i + 1) % 3 == 0)
        {
            cout << endl;
        }
        cout << endl;
    }
}

bool solveSudoku(int mat[][9], int i, int j)
{
    ///Base Case
    if (i == 9)
    {
        ///Solve kr chuke hain for 9 rows already
        printMat(mat);
        return true;
    }

    ///Crossed the last  Cell in the row
    if (j == 9)
    {
        return solveSudoku(mat, i + 1, 0);
    }

    ///Blue Cell - Skip
    if (mat[i][j] != 0)
    {
        return solveSudoku(mat, i, j + 1);
    }
    ///White Cell
    ///Try to place every possible no
    for (int no = 1; no <= 9; no++)
    {
        if (isPossible(mat, i, j, no))
        {
            ///Place the no - assuming solution aa jayega
            mat[i][j] = no;
            bool aageKiSolveHui = solveSudoku(mat, i, j + 1);
            if (aageKiSolveHui)
            {
                return true;
            }
            ///Nahin solve hui
            ///loop will place the next no.
        }
    }
    ///Sare no try kr liey, kisi se bhi solve nahi hui
    mat[i][j] = 0;
    return false;
}

int main()
{

    int mat[9][9] =
        {{5, 3, 0, 0, 7, 0, 0, 0, 0},
         {6, 0, 0, 1, 9, 5, 0, 0, 0},
         {0, 9, 8, 0, 0, 0, 0, 6, 0},
         {8, 0, 0, 0, 6, 0, 0, 0, 3},
         {4, 0, 0, 8, 0, 3, 0, 0, 1},
         {7, 0, 0, 0, 2, 0, 0, 0, 6},
         {0, 6, 0, 0, 0, 0, 2, 8, 0},
         {0, 0, 0, 4, 1, 9, 0, 0, 5},
         {0, 0, 0, 0, 8, 0, 0, 7, 9}};

    printMat(mat);
    cout << "Solution " << endl;
    solveSudoku(mat, 0, 0);

    return 0;
}

贪心算法

Dijkstra

#include 
#include 

using namespace std;

//Wrapper class for storing a graph
class Graph
{
public:
    int vertexNum;
    int **edges;

    //Constructs a graph with V vertices and E edges
    Graph(const int V)
    {

        // initializes the array edges.
        this->edges = new int *[V];
        for (int i = 0; i < V; i++)
        {
            edges[i] = new int[V];
        }

        // fills the array with zeros.
        for (int i = 0; i < V; i++)
        {
            for (int j = 0; j < V; j++)
            {
                edges[i][j] = 0;
            }
        }

        this->vertexNum = V;
    }

    //Adds the given edge to the graph
    void addEdge(int src, int dst, int weight)
    {
        this->edges[src][dst] = weight;
    }
};
//Utility function to find minimum distance vertex in mdist
int minDistance(int mdist[], bool vset[], int V)
{
    int minVal = INT_MAX, minInd = 0;
    for (int i = 0; i < V; i++)
    {
        if (!vset[i] && (mdist[i] < minVal))
        {
            minVal = mdist[i];
            minInd = i;
        }
    }

    return minInd;
}

//Utility function to print distances
void print(int dist[], int V)
{
    cout << "\nVertex  Distance" << endl;
    for (int i = 0; i < V; i++)
    {
        if (dist[i] < INT_MAX)
            cout << i << "\t" << dist[i] << endl;
        else
            cout << i << "\tINF" << endl;
    }
}

//The main function that finds the shortest path from given source
//to all other vertices using Dijkstra's Algorithm.It doesn't work on negative
//weights
void Dijkstra(Graph graph, int src)
{
    int V = graph.vertexNum;
    int mdist[V]; //Stores updated distances to vertex
    bool vset[V]; // vset[i] is true if the vertex i included
    // in the shortest path tree

    //Initialise mdist and vset. Set distance of source as zero
    for (int i = 0; i < V; i++)
    {
        mdist[i] = INT_MAX;
        vset[i] = false;
    }

    mdist[src] = 0;

    //iterate to find shortest path
    for (int count = 0; count < V - 1; count++)
    {
        int u = minDistance(mdist, vset, V);

        vset[u] = true;

        for (int v = 0; v < V; v++)
        {
            if (!vset[v] && graph.edges[u][v] && mdist[u] + graph.edges[u][v] < mdist[v])
            {
                mdist[v] = mdist[u] + graph.edges[u][v];
            }
        }
    }

    print(mdist, V);
}

//Driver Function
int main()
{
    int V, E, gsrc;
    int src, dst, weight;
    cout << "Enter number of vertices: ";
    cin >> V;
    cout << "Enter number of edges: ";
    cin >> E;
    Graph G(V);
    for (int i = 0; i < E; i++)
    {
        cout << "\nEdge " << i + 1 << "\nEnter source: ";
        cin >> src;
        cout << "Enter destination: ";
        cin >> dst;
        cout << "Enter weight: ";
        cin >> weight;

        // makes sure source and destionation are in the proper bounds.
        if (src >= 0 && src < V && dst >= 0 && dst < V)
        {
            G.addEdge(src, dst, weight);
        }
        else
        {
            cout << "source and/or destination out of bounds" << endl;
            i--;
            continue;
        }
    }
    cout << "\nEnter source:";
    cin >> gsrc;
    Dijkstra(G, gsrc);

    return 0;
}

Knapsack

#include 
using namespace std;

struct Item
{
	int weight;
	int profit;
};

float profitPerUnit(Item x)
{
	return (float)x.profit / (float)x.weight;
}

int partition(Item arr[], int low, int high)
{
	Item pivot = arr[high]; // pivot
	int i = (low - 1);		// Index of smaller element

	for (int j = low; j < high; j++)
	{
		// If current element is smaller than or
		// equal to pivot
		if (profitPerUnit(arr[j]) <= profitPerUnit(pivot))
		{
			i++; // increment index of smaller element
			Item temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}
	}
	Item temp = arr[i + 1];
	arr[i + 1] = arr[high];
	arr[high] = temp;
	return (i + 1);
}

void quickSort(Item arr[], int low, int high)
{
	if (low < high)
	{

		int p = partition(arr, low, high);

		quickSort(arr, low, p - 1);
		quickSort(arr, p + 1, high);
	}
}

int main()
{
	cout << "\nEnter the capacity of the knapsack : ";
	float capacity;
	cin >> capacity;
	cout << "\n Enter the number of Items : ";
	int n;
	cin >> n;
	Item itemArray[n];
	for (int i = 0; i < n; i++)
	{
		cout << "\nEnter the weight and profit of item " << i + 1 << " : ";
		cin >> itemArray[i].weight;
		cin >> itemArray[i].profit;
	}

	quickSort(itemArray, 0, n - 1);

	// show(itemArray, n);

	float maxProfit = 0;
	int i = n;
	while (capacity > 0 && --i >= 0)
	{
		if (capacity >= itemArray[i].weight)
		{
			maxProfit += itemArray[i].profit;
			capacity -= itemArray[i].weight;
			cout << "\n\t" << itemArray[i].weight << "\t" << itemArray[i].profit;
		}
		else
		{
			maxProfit += profitPerUnit(itemArray[i]) * capacity;
			cout << "\n\t" << capacity << "\t" << profitPerUnit(itemArray[i]) * capacity;
			capacity = 0;
			break;
		}
	}

	cout << "\nMax Profit : " << maxProfit;

	return 0;
}

Kruskals Minimum Spanning Tree

#include 
using namespace std;

#define V 6
#define INFINITY 99999

int graph[V][V] = {
	{0, 4, 1, 4, INFINITY, INFINITY},
	{4, 0, 3, 8, 3, INFINITY},
	{1, 3, 0, INFINITY, 1, INFINITY},
	{4, 8, INFINITY, 0, 5, 7},
	{INFINITY, 3, 1, 5, 0, INFINITY},
	{INFINITY, INFINITY, INFINITY, 7, INFINITY, 0}};

void findMinimumEdge()
{
	for (int i = 0; i < V; i++)
	{
		int min = INFINITY;
		int minIndex = 0;
		for (int j = 0; j < V; j++)
		{
			if (graph[i][j] != 0 && graph[i][j] < min)
			{
				min = graph[i][j];
				minIndex = j;
			}
		}
		cout << i << "  -  " << minIndex << "\t" << graph[i][minIndex] << "\n";
	}
}

int main()
{
	findMinimumEdge();
	return 0;
}

Primes Minimum Spanning Tree

#include 
using namespace std;

#define V 4
#define INFINITY 99999

int graph[V][V] = {
	{0, 5, 1, 2},
	{5, 0, 3, 3},
	{1, 3, 0, 4},
	{2, 3, 4, 0}};

struct mst
{
	bool visited;
	int key;
	int near;
};

mst MST_Array[V];

void initilize()
{
	for (int i = 0; i < V; i++)
	{
		MST_Array[i].visited = false;
		MST_Array[i].key = INFINITY; // considering INFINITY as inifinity
		MST_Array[i].near = i;
	}

	MST_Array[0].key = 0;
}

void updateNear()
{
	for (int v = 0; v < V; v++)
	{
		int min = INFINITY;
		int minIndex = 0;
		for (int i = 0; i < V; i++)
		{
			if (MST_Array[i].key < min && MST_Array[i].visited == false && MST_Array[i].key != INFINITY)
			{
				min = MST_Array[i].key;
				minIndex = i;
			}
		}

		MST_Array[minIndex].visited = true;

		for (int i = 0; i < V; i++)
		{
			if (graph[minIndex][i] != 0 && graph[minIndex][i] < INFINITY)
			{
				if (graph[minIndex][i] < MST_Array[i].key)
				{
					MST_Array[i].key = graph[minIndex][i];
					MST_Array[i].near = minIndex;
				}
			}
		}
	}
}

void show()
{
	for (int i = 0; i < V; i++)
	{
		cout << i << "  -  " << MST_Array[i].near << "\t" << graph[i][MST_Array[i].near] << "\n";
	}
}

int main()
{
	initilize();
	updateNear();
	show();
	return 0;
}

Huffman

// C++ program for Huffman Coding 
#include 
#include  
using namespace std; 
  
// A Huffman tree node 
struct MinHeapNode { 
  
    // One of the input characters 
    char data; 
  
    // Frequency of the character 
    unsigned freq; 
  
    // Left and right child 
    MinHeapNode *left, *right; 
  
    MinHeapNode(char data, unsigned freq) 
  
    { 
  
        left = right = NULL; 
        this->data = data; 
        this->freq = freq; 
    } 
}; 
  
// For comparison of 
// two heap nodes (needed in min heap) 
struct compare { 
  
    bool operator()(MinHeapNode* l, MinHeapNode* r) 
  
    { 
        return (l->freq > r->freq); 
    } 
}; 
  
// Prints huffman codes from 
// the root of Huffman Tree. 
void printCodes(struct MinHeapNode* root, string str) 
{ 
  
    if (!root) 
        return; 
  
    if (root->data != '$') 
        cout << root->data << ": " << str << "\n"; 
  
    printCodes(root->left, str + "0"); 
    printCodes(root->right, str + "1"); 
} 
  
// The main function that builds a Huffman Tree and 
// print codes by traversing the built Huffman Tree 
void HuffmanCodes(char data[], int freq[], int size) 
{ 
    struct MinHeapNode *left, *right, *top; 
  
    // Create a min heap & inserts all characters of data[] 
    priority_queue<MinHeapNode*, vector<MinHeapNode*>, compare> minHeap; 
  
    for (int i = 0; i < size; ++i) 
        minHeap.push(new MinHeapNode(data[i], freq[i])); 
  
    // Iterate while size of heap doesn't become 1 
    while (minHeap.size() != 1) { 
  
        // Extract the two minimum 
        // freq items from min heap 
        left = minHeap.top(); 
        minHeap.pop(); 
  
        right = minHeap.top(); 
        minHeap.pop(); 
  
        // Create a new internal node with 
        // frequency equal to the sum of the 
        // two nodes frequencies. Make the 
        // two extracted node as left and right children 
        // of this new node. Add this node 
        // to the min heap '$' is a special value 
        // for internal nodes, not used 
        top = new MinHeapNode('$', left->freq + right->freq); 
  
        top->left = left; 
        top->right = right; 
  
        minHeap.push(top); 
    } 
  
    // Print Huffman codes using 
    // the Huffman tree built above 
    printCodes(minHeap.top(), ""); 
} 
  
// Driver program to test above functions 
int main() 
{ 
  
    char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' }; 
    int freq[] = { 5, 9, 12, 13, 16, 45 }; 
  
    int size = sizeof(arr) / sizeof(arr[0]); 
  
    HuffmanCodes(arr, freq, size); 
  
    return 0; 
} 

图论算法

BFS

#include 
using namespace std;
class graph
{
	int v;
	list<int> *adj;

public:
	graph(int v);
	void addedge(int src, int dest);
	void printgraph();
	void bfs(int s);
};
graph::graph(int v)
{
	this->v = v;
	this->adj = new list<int>[v];
}
void graph::addedge(int src, int dest)
{
	src--;
	dest--;
	adj[src].push_back(dest);
	//adj[dest].push_back(src);
}
void graph::printgraph()
{
	for (int i = 0; i < this->v; i++)
	{
		cout << "Adjacency list of vertex " << i + 1 << " is \n";
		list<int>::iterator it;
		for (it = adj[i].begin(); it != adj[i].end(); ++it)
		{
			cout << *it + 1 << " ";
		}
		cout << endl;
	}
}
void graph::bfs(int s)
{
	bool *visited = new bool[this->v + 1];
	memset(visited, false, sizeof(bool) * (this->v + 1));
	visited[s] = true;
	list<int> q;
	q.push_back(s);
	list<int>::iterator it;
	while (!q.empty())
	{
		int u = q.front();
		cout << u << " ";
		q.pop_front();
		for (it = adj[u].begin(); it != adj[u].end(); ++it)
		{
			if (visited[*it] == false)
			{
				visited[*it] = true;
				q.push_back(*it);
			}
		}
	}
}
int main()
{
	graph g(4);
	g.addedge(1, 2);
	g.addedge(2, 3);
	g.addedge(3, 4);
	g.addedge(1, 4);
	g.addedge(1, 3);
	//g.printgraph();
	g.bfs(2);
	return 0;
}

DFS

#include 
using namespace std;
int v = 4;
void DFSUtil_(int graph[4][4], bool visited[], int s)
{
	visited[s] = true;
	cout << s << " ";
	for (int i = 0; i < v; i++)
	{
		if (graph[s][i] == 1 && visited[i] == false)
		{
			DFSUtil_(graph, visited, i);
		}
	}
}

void DFS_(int graph[4][4], int s)
{
	bool visited[v];
	memset(visited, 0, sizeof(visited));
	DFSUtil_(graph, visited, s);
}

int main()
{
	int graph[4][4] = {{0, 1, 1, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}, {0, 0, 0, 1}};
	cout << "DFS: ";
	DFS_(graph, 2);
	cout << endl;
	return 0;
}

DFS with Stack

#include 
#include 
#include 

#define WHITE 0
#define GREY 1
#define BLACK 2
#define INF 99999

using namespace std;

int checked[999] = {WHITE};

void dfs(const list<int> lista[], int start)
{
    stack<int> stack;

    int checked[999] = {WHITE};

    stack.push(start);

    checked[start] = GREY;
    while (!stack.empty())
    {
        int act = stack.top();
        stack.pop();

        if (checked[act] == GREY)
        {
            cout << act << ' ';
            for (auto it = lista[act].begin(); it != lista[act].end(); ++it)
            {
                stack.push(*it);
                if (checked[*it] != BLACK)
                    checked[*it] = GREY;
            }
            checked[act] = BLACK; //nodo controllato
        }
    }
}

int main()
{
    int u, w;
    int n;
    cin >> n;
    list<int> lista[INF];
    for (int i = 0; i < n; ++i)
    {
        cin >> u >> w;
        lista[u].push_back(w);
    }

    dfs(lista, 0);

    return 0;
}

Dijkstra

#include 
#include 
#include 
#include 
using namespace std;
#define INF 10000010
vector<pair<int, int>> graph[5 * 100001];
int dis[5 * 100001];
int dij(vector<pair<int, int>> *v, int s, int *dis)
{
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    // source distance to zero.
    pq.push(make_pair(0, s));
    dis[s] = 0;
    int u;
    while (!pq.empty())
    {
        u = (pq.top()).second;
        pq.pop();
        for (vector<pair<int, int>>::iterator it = v[u].begin(); it != v[u].end(); it++)
        {
            if (dis[u] + it->first < dis[it->second])
            {
                dis[it->second] = dis[u] + it->first;
                pq.push(make_pair(dis[it->second], it->second));
            }
        }
    }
}
int main()
{
    int m, n, l, x, y, s;
    // n--> number of nodes , m --> number of edges
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        // input edges.
        scanf("%d%d%d", &x, &y, &l);
        graph[x].push_back(make_pair(l, y));
        graph[y].push_back(make_pair(l, x)); // comment this line for directed graph
    }
    // start node.
    scanf("%d", &s);
    // intialise all distances to infinity.
    for (int i = 1; i <= n; i++)
        dis[i] = INF;
    dij(graph, s, dis);

    for (int i = 1; i <= n; i++)
        if (dis[i] == INF)
            cout << "-1 ";
        else
            cout << dis[i] << " ";
    return 0;
}

Kruskal

#include 
//#include 
//using namespace boost::multiprecision;
const int mx = 1e6 + 5;
const long int inf = 2e9;
typedef long long ll;
#define rep(i, n) for (i = 0; i < n; i++)
#define repp(i, a, b) for (i = a; i <= b; i++)
#define pii pair
#define vpii vector
#define vi vector
#define vll vector
#define r(x) scanf("%d", &x)
#define rs(s) scanf("%s", s)
#define gc getchar_unlocked
#define pc putchar_unlocked
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define endl "\n"
#define fast                          \
	ios_base::sync_with_stdio(false); \
	cin.tie(NULL);                    \
	cout.tie(NULL);
using namespace std;
void in(int &x)
{
	register int c = gc();
	x = 0;
	int neg = 0;
	for (; ((c < 48 || c > 57) && c != '-'); c = gc())
		;
	if (c == '-')
	{
		neg = 1;
		c = gc();
	}
	for (; c > 47 && c < 58; c = gc())
	{
		x = (x << 1) + (x << 3) + c - 48;
	}
	if (neg)
		x = -x;
}
void out(int n)
{
	int N = n, rev, count = 0;
	rev = N;
	if (N == 0)
	{
		pc('0');
		return;
	}
	while ((rev % 10) == 0)
	{
		count++;
		rev /= 10;
	}
	rev = 0;
	while (N != 0)
	{
		rev = (rev << 3) + (rev << 1) + N % 10;
		N /= 10;
	}
	while (rev != 0)
	{
		pc(rev % 10 + '0');
		rev /= 10;
	}
	while (count--)
		pc('0');
}
ll parent[mx], arr[mx], node, edge;
vector<pair<ll, pair<ll, ll>>> v;
void initial()
{
	int i;
	rep(i, node + edge)
		parent[i] = i;
}
int root(int i)
{
	while (parent[i] != i)
	{
		parent[i] = parent[parent[i]];
		i = parent[i];
	}
	return i;
}
void join(int x, int y)
{
	int root_x = root(x); //Disjoint set union by rank
	int root_y = root(y);
	parent[root_x] = root_y;
}
ll kruskal()
{
	ll mincost = 0, i, x, y;
	rep(i, edge)
	{
		x = v[i].second.first;
		y = v[i].second.second;
		if (root(x) != root(y))
		{
			mincost += v[i].first;
			join(x, y);
		}
	}
	return mincost;
}
int main()
{
	fast;
	while (1)
	{
		int i, j, from, to, cost, totalcost = 0;
		cin >> node >> edge; //Enter the nodes and edges
		if (node == 0 && edge == 0)
			break; //Enter 0 0 to break out
		initial(); //Initialise the parent array
		rep(i, edge)
		{
			cin >> from >> to >> cost;
			v.pb(mp(cost, mp(from, to)));
			totalcost += cost;
		}
		sort(v.begin(), v.end());
		// rep(i,v.size())
		// 	cout<
		cout << kruskal() << endl;
		v.clear();
	}
	return 0;
}

Topological Sort

#include 
#include 
#include 
using namespace std;

int n, m; // For number of Vertices (V) and number of edges (E)
vector<vector<int>> G;
vector<bool> visited;
vector<int> ans;

void dfs(int v)
{
  visited[v] = true;
  for (int u : G[v])
  {
    if (!visited[u])
      dfs(u);
  }
  ans.push_back(v);
}

void topological_sort()
{
  visited.assign(n, false);
  ans.clear();
  for (int i = 0; i < n; ++i)
  {
    if (!visited[i])
      dfs(i);
  }
  reverse(ans.begin(), ans.end());
}
int main()
{
  cout << "Enter the number of vertices and the number of directed edges\n";
  cin >> n >> m;
  int x, y;
  G.resize(n, vector<int>());
  for (int i = 0; i < n; ++i)
  {
    cin >> x >> y;
    x--, y--; // to convert 1-indexed to 0-indexed
    G[x].push_back(y);
  }
  topological_sort();
  cout << "Topological Order : \n";
  for (int v : ans)
  {
    cout << v + 1 << ' '; // converting zero based indexing back to one based.
  }
  cout << '\n';
  return 0;
}

Kosaraju

/* Implementation of Kosaraju's Algorithm to find out the strongly connected components (SCCs) in a graph. 
   Author:Anirban166
*/   

#include
#include

using namespace std;

/**
* Iterative function/method to print graph:
* @param a[] : array of vectors (2D)
* @param V : vertices
* @return void 
**/
void print(vector<int> a[],int V)
{
    for(int i=0;i<V;i++)
    {
        if(!a[i].empty())
            cout<<"i="<<i<<"-->";
        for(int j=0;j<a[i].size();j++)
            cout<<a[i][j]<<" ";
        if(!a[i].empty())
            cout<<endl;
    }
}

/**
* //Recursive function/method to push vertices into stack passed as parameter:
* @param v : vertices
* @param &st : stack passed by reference
* @param vis[] : array to keep track of visited nodes (boolean type)
* @param adj[] : array of vectors to represent graph
* @return void 
**/
void push_vertex(int v,stack<int> &st,bool vis[],vector<int> adj[])
{
    vis[v]=true;
    for(auto i=adj[v].begin();i!=adj[v].end();i++)
    {
        if(vis[*i]==false)
            push_vertex(*i,st,vis,adj);
    }
    st.push(v);
}


/**
* //Recursive function/method to implement depth first traversal(dfs):
* @param v : vertices
* @param vis[] : array to keep track of visited nodes (boolean type)
* @param grev[] : graph with reversed edges
* @return void 
**/
void dfs(int v,bool vis[],vector<int> grev[])
{
    vis[v]=true;
    // cout<
    for(auto i=grev[v].begin();i!=grev[v].end();i++)
    {
        if(vis[*i]==false)
            dfs(*i,vis,grev);
    }
}

//function/method to implement Kosaraju's Algorithm:
/**
* Info about the method
* @param V : vertices in graph
* @param adj[] : array of vectors that represent a graph (adjacency list/array)
* @return int ( 0, 1, 2..and so on, only unsigned values as either there can be no SCCs i.e. none(0) or there will be x no. of SCCs (x>0))
   i.e. it returns the count of (number of) strongly connected components (SCCs) in the graph. (variable 'count_scc' within function)
**/
int kosaraju(int V, vector<int> adj[])
{
    bool vis[V]={};
    stack<int> st;
    for(int v=0;v<V;v++)
    {
        if(vis[v]==false)
            push_vertex(v,st,vis,adj);
    }
    //making new graph (grev) with reverse edges as in adj[]:
    vector<int> grev[V];
    for(int i=0;i<V+1;i++)
    {
        for(auto j=adj[i].begin();j!=adj[i].end();j++)
        {
            grev[*j].push_back(i);
        }
    }
    // cout<<"grev="<debug statement
    // print(grev,V);       ->debug statement
    //reinitialise visited to 0
    for(int i=0;i<V;i++)
        vis[i]=false;
    int count_scc=0;
    while(!st.empty())
    {
        int t=st.top();
        st.pop();
        if(vis[t]==false)
        {
            dfs(t,vis,grev);
            count_scc++;
        }
    }
    // cout<<"count_scc="<
    return count_scc;
}

//All critical/corner cases have been taken care of.
//Input your required values: (not hardcoded)
int main()
{
    int t;
    cin>>t; 
    while(t--)
    {
        int a,b ; //a->number of nodes, b->directed edges.
   	  cin>>a>>b;
   	  int m,n;
   	  vector<int> adj[a+1];
        for(int i=0;i<b;i++) //take total b inputs of 2 vertices each required to form an edge.
        {
            cin>>m>>n; //take input m,n denoting edge from m->n.
            adj[m].push_back(n);
        }
        //pass number of nodes and adjacency array as parameters to function:
        cout<<kosaraju(a, adj)<<endl;
    }
    return 0;
}

LCA

//#include
#include 

using namespace std;
// Find the lowest common ancestor using binary lifting in O(nlogn)
// Zero based indexing
// Resource : https://cp-algorithms.com/graph/lca_binary_lifting.html
const int N = 1005;
const int LG = log2(N) + 1;
struct lca
{
    int n;
    vector<int> adj[N]; // Graph
    int up[LG][N]; // build this table
    int level[N]; // get the levels of all of them

    lca(int n_): n(n_)
    {
        memset(up, -1, sizeof(up));
        memset(level, 0, sizeof(level));
        for (int i = 0; i < n - 1; ++i)
	{
            int a, b;
            cin >> a >> b;
            a--;
            b--;
            adj[a].push_back(b);
            adj[b].push_back(a);
        }
        level[0] = 0;
        dfs(0, -1);
        build();
    }
    void verify()
    {
        for (int i = 0; i < n; ++i)
	{
            cout << i << " : level: " << level[i] << endl;
        }
        cout << endl;
        for (int i = 0; i < LG; ++i)
	{
            cout << "Power:" << i << ": ";
            for (int j = 0; j < n; ++j)
	    {
                cout << up[i][j] << " ";
            }
            cout << endl;
        }
    }

    void build()
    {
        for (int i = 1; i < LG; ++i)
	{
            for (int j = 0; j < n; ++j)
	    {
                if (up[i - 1][j] != -1)
		{
                    up[i][j] = up[i - 1][up[i - 1][j]];
                }
            }
        }
    }

    void dfs(int node, int par)
    {
        up[0][node] = par;
        for (auto i: adj[node])
	{
            if (i != par)
	    {
                level[i] = level[node] + 1;
                dfs(i, node);
            }
        }
    }
    int query(int u, int v)
    {
        u--;
        v--;
        if (level[v] > level[u])
	{
            swap(u, v);
        }
        // u is at the bottom.
        int dist = level[u] - level[v];
        // Go up this much distance
        for (int i = LG - 1; i >= 0; --i)
	{
            if (dist & (1 << i))
	    {
                u = up[i][u];
            }
        }
        if (u == v)
	{
            return u;
        }
        assert(level[u] == level[v]);
        for (int i = LG - 1; i >= 0; --i)
	{
            if (up[i][u] != up[i][v])
	    {
                u = up[i][u];
                v = up[i][v];
            }
        }
        assert(up[0][u] == up[0][v]);
        return up[0][u];
    }
};

int main()
{
    int n; // number of nodes in the tree.
    lca l(n); // will take the input in the format given
    // n-1 edges of the form
    // a b
    // Use verify function to see.
}

动态规划

0-1 Knapsack problem

//#include 
#include 
using namespace std;

//void Print(int res[20][20], int i, int j, int capacity)
//{
//	if(i==0 || j==0)
//	{
//		return;
//	}
//	if(res[i-1][j]==res[i][j-1])
//	{
//		if(i<=capacity)
//		{
//			cout<
//		}
//
//		Print(res, i-1, j-1, capacity-i);
//	}
//	else if(res[i-1][j]>res[i][j-1])
//	{
//		Print(res, i-1,j, capacity);
//	}
//	else if(res[i][j-1]>res[i-1][j])
//	{
//		Print(res, i,j-1, capacity);
//	}
//}

int Knapsack(int capacity, int n, int weight[], int value[])
{
	int res[20][20];
	for (int i = 0; i < n + 1; ++i)
	{
		for (int j = 0; j < capacity + 1; ++j)
		{
			if (i == 0 || j == 0)
				res[i][j] = 0;
			else if (weight[i - 1] <= j)
				res[i][j] = max(value[i - 1] + res[i - 1][j - weight[i - 1]], res[i - 1][j]);
			else
				res[i][j] = res[i - 1][j];
		}
	}
	//	Print(res, n, capacity, capacity);
	//	cout<<"\n";
	return res[n][capacity];
}
int main()
{
	int n;
	cout << "Enter number of items: ";
	cin >> n;
	int weight[n], value[n];
	cout << "Enter weights: ";
	for (int i = 0; i < n; ++i)
	{
		cin >> weight[i];
	}
	cout << "Enter values: ";
	for (int i = 0; i < n; ++i)
	{
		cin >> value[i];
	}
	int capacity;
	cout << "Enter capacity: ";
	cin >> capacity;
	cout << Knapsack(capacity, n, weight, value);
	return 0;
}

Bellman Ford

#include 
#include 

using namespace std;

//Wrapper class for storing an edge
class Edge
{
public:
	int src, dst, weight;
};

//Wrapper class for storing a graph
class Graph
{
public:
	int vertexNum, edgeNum;
	Edge *edges;

	//Constructs a graph with V vertices and E edges
	Graph(int V, int E)
	{
		this->vertexNum = V;
		this->edgeNum = E;
		this->edges = (Edge *)malloc(E * sizeof(Edge));
	}

	//Adds the given edge to the graph
	void addEdge(int src, int dst, int weight)
	{
		static int edgeInd = 0;
		if (edgeInd < this->edgeNum)
		{
			Edge newEdge;
			newEdge.src = src;
			newEdge.dst = dst;
			newEdge.weight = weight;
			this->edges[edgeInd++] = newEdge;
		}
	}
};

//Utility function to print distances
void print(int dist[], int V)
{
	cout << "\nVertex  Distance" << endl;
	for (int i = 0; i < V; i++)
	{
		if (dist[i] != INT_MAX)
			cout << i << "\t" << dist[i] << endl;
		else
			cout << i << "\tINF" << endl;
	}
}

//The main function that finds the shortest path from given source
//to all other vertices using Bellman-Ford.It also detects negative
//weight cycle
void BellmanFord(Graph graph, int src)
{
	int V = graph.vertexNum;
	int E = graph.edgeNum;
	int dist[V];

	//Initialize distances array as INF for all except source
	//Intialize source as zero
	for (int i = 0; i < V; i++)
		dist[i] = INT_MAX;
	dist[src] = 0;

	//Calculate shortest path distance from source to all edges
	//A path can contain maximum (|V|-1) edges
	for (int i = 0; i <= V - 1; i++)
		for (int j = 0; j < E; j++)
		{
			int u = graph.edges[j].src;
			int v = graph.edges[j].dst;
			int w = graph.edges[j].weight;

			if (dist[u] != INT_MAX && dist[u] + w < dist[v])
				dist[v] = dist[u] + w;
		}

	//Iterate inner loop once more to check for negative cycle
	for (int j = 0; j < E; j++)
	{
		int u = graph.edges[j].src;
		int v = graph.edges[j].dst;
		int w = graph.edges[j].weight;

		if (dist[u] != INT_MAX && dist[u] + w < dist[v])
		{
			cout << "Graph contains negative weight cycle. Hence, shortest distance not guaranteed." << endl;
			return;
		}
	}

	print(dist, V);

	return;
}

//Driver Function
int main()
{
	int V, E, gsrc;
	int src, dst, weight;
	cout << "Enter number of vertices: ";
	cin >> V;
	cout << "Enter number of edges: ";
	cin >> E;
	Graph G(V, E);
	for (int i = 0; i < E; i++)
	{
		cout << "\nEdge " << i + 1 << "\nEnter source: ";
		cin >> src;
		cout << "Enter destination: ";
		cin >> dst;
		cout << "Enter weight: ";
		cin >> weight;
		G.addEdge(src, dst, weight);
	}
	cout << "\nEnter source: ";
	cin >> gsrc;
	BellmanFord(G, gsrc);

	return 0;
}

Catalan Numbers

/** Print all the Catalan numbers from 0 to n, n being the user input.
 * A Catalan number satifies the following two properties:
 * C(0) = C(1) = 1; C(n) = sum(C(i).C(n-i-1)), from i = 0 to n-1
 * Read more about Catalan numbers here:
    https://en.wikipedia.org/wiki/Catalan_number
 */

#include 
using namespace std;

int *cat; // global array to hold catalan numbers

unsigned long int catalan_dp(int n)
{
    /** Using the tabulation technique in dynamic programming,
        this function computes the first `n+1` Catalan numbers
        Parameter
        ---------
        n: The number of catalan numbers to be computed.
        Returns
        -------
        cat[n]: An array containing the first `n+1` Catalan numbers
    */

    // By definition, the first two Catalan numbers are 1
    cat[0] = cat[1] = 1;

    // Compute the remaining numbers from index 2 to index n, using tabulation
    for (int i = 2; i <= n; i++)
    {
        cat[i] = 0;
        for (int j = 0; j < i; j++)
            cat[i] += cat[j] * cat[i - j - 1]; // applying the definition here
    }

    // Return the result
    return cat[n];
}

int main(int argc, char *argv[])
{
    int n;
    cout << "Enter n: ";
    cin >> n;

    cat = new int[n + 1];

    cout << "Catalan numbers from 0 to " << n << " are:\n";
    for (int i = 0; i <= n; i++)
    {
        cout << "catalan (" << i << ") = " << catalan_dp(i) << endl;
        // NOTE: Since `cat` is a global array, calling `catalan_dp`
        // repeatedly will not recompute the the values already computed
        // as in case of pre-computed values, the array will simply return them,
        // instead of recomputing them.
    }

    return 0;
}

/** Sample Test Case:
$ cd "Dynamic Programming"
$ g++ Catalan-Numbers.cpp
$ ./a.exe
Enter n: 5
Catalan numbers from 0 to 5 are:
catalan (0) = 1
catalan (1) = 1
catalan (2) = 2
catalan (3) = 5
catalan (4) = 14
catalan (5) = 42
*/

Coin Change

#include 
#include 
using namespace std;

// Function to find the Minimum number of coins required to get Sum S
int findMinCoins(int arr[], int n, int N)
{
	// dp[i] = no of coins required to get a total of i
	int dp[N + 1];

	// 0 coins are needed for 0 sum

	dp[0] = 0;

	for (int i = 1; i <= N; i++)
	{
		// initialize minimum number of coins needed to infinity
		dp[i] = INT_MAX;
		int res = INT_MAX;

		// do for each coin
		for (int c = 0; c < n; c++)
		{
			if (i - arr[c] >= 0) // check if coins doesn't become negative by including it
				res = dp[i - arr[c]];

			// if total can be reached by including current coin c,
			// update minimum number of coins needed dp[i]
			if (res != INT_MAX)
				dp[i] = min(dp[i], res + 1);
		}
	}

	// The Minimum No of Coins Required for N = dp[N]
	return dp[N];
}

int main()
{
	// No of Coins We Have
	int arr[] = {1, 2, 3, 4};
	int n = sizeof(arr) / sizeof(arr[0]);

	// Total Change Required
	int N = 15;

	cout << "Minimum Number of Coins Required " << findMinCoins(arr, n, N) << "\n";

	return 0;
}

Cut Rod

/*Given a rod of length n inches and an array of prices that 
contains prices of all pieces of size smaller than n. Determine 
the maximum value obtainable by cutting up the rod and selling 
the pieces.*/

#include 
using namespace std;
int cutrod(int p[], int n)
{
    int r[n + 1];
    r[0] = 0;
    for (int j = 0; j < n; j++)
    {
        int q = INT_MIN;
        for (int i = 0; i <= j; i++)
        {
            q = max(q, p[i] + r[j - i]);
        }
        r[j + 1] = q;
    }
    return r[n];
}
int main()
{
    int price[] = {1, 5, 8, 9, 10, 17, 17, 20, 24, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50};
    cout << cutrod(price, 30);
    return 0;
}

Edit Distance

/* Given two strings str1 & str2
 * and below operations that can
 * be performed on str1. Find
 * minimum number of edits
 * (operations) required to convert
 * 'str1' into 'str2'/
 * a. Insert
 * b. Remove
 * c. Replace
 * All of the above operations are 
 * of equal cost
 */

#include 
#include 
using namespace std;

int min(int x, int y, int z)
{
    return min(min(x, y), z);
}

/* A Naive recursive C++ program to find
 * minimum number of operations to convert
 * str1 to str2.
 * O(3^m)
 */
int editDist(string str1, string str2, int m, int n)
{
    if (m == 0)
        return n;
    if (n == 0)
        return m;

    //If last characters are same then continue
    //for the rest of them.
    if (str1[m - 1] == str2[n - 1])
        return editDist(str1, str2, m - 1, n - 1);

    //If last not same, then 3 possibilities
    //a.Insert b.Remove c. Replace
    //Get min of three and continue for rest.
    return 1 + min(editDist(str1, str2, m, n - 1),
                   editDist(str1, str2, m - 1, n),
                   editDist(str1, str2, m - 1, n - 1));
}

/* A DP based program
 * O(m x n)
 */
int editDistDP(string str1, string str2, int m, int n)
{

    //Create Table for SubProblems
    int dp[m + 1][n + 1];

    //Fill d[][] in bottom up manner
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            //If str1 empty. Then add all of str2
            if (i == 0)
                dp[i][j] = j;

            //If str2 empty. Then add all of str1
            else if (j == 0)
                dp[i][j] = i;

            //If character same. Recur for remaining
            else if (str1[i - 1] == str2[j - 1])
                dp[i][j] = dp[i - 1][j - 1];

            else
                dp[i][j] = 1 + min(dp[i][j - 1],    //Insert
                                   dp[i - 1][j],    //Remove
                                   dp[i - 1][j - 1] //Replace
                               );
        }
    }

    return dp[m][n];
}

int main()
{
    string str1 = "sunday";
    string str2 = "saturday";

    cout << editDist(str1, str2, str1.length(), str2.length()) << endl;
    cout << editDistDP(str1, str2, str1.length(), str2.length()) << endl;

    return 0;
}

Egg Droping Puzzle

/* Function to get minimun number of trials needed 
 * in worst case with n eggs and k floors 
 */

#include 
#include 
using namespace std;

int eggDrop(int n, int k)
{
    int eggFloor[n + 1][k + 1];
    int result;

    for (int i = 1; i <= n; i++)
    {
        eggFloor[i][1] = 1; //n eggs..1 Floor
        eggFloor[i][0] = 0; //n eggs..0 Floor
    }

    // Only one egg available
    for (int j = 1; j <= k; j++)
    {
        eggFloor[1][j] = j;
    }

    for (int i = 2; i <= n; i++)
    {
        for (int j = 2; j <= k; j++)
        {
            eggFloor[i][j] = INT_MAX;
            for (int x = 1; x <= j; x++)
            {
                // 1+max(eggBreak[one less egg, lower floors],
                //       eggDoesntBreak[same ## of eggs, upper floors]);
                result = 1 + max(eggFloor[i - 1][x - 1], eggFloor[i][j - x]);
                if (result < eggFloor[i][j])
                    eggFloor[i][j] = result;
            }
        }
    }

    return eggFloor[n][k];
}

int main()
{
    int n, k;
    cout << "Enter number of eggs and floors: ";
    cin >> n >> k;
    cout << "Minimum number of trials in worst case: " << eggDrop(n, k) << endl;
    return 0;
}

Fibonacci Bottom Up

#include 
using namespace std;
int fib(int n)
{
	int res[3];
	res[0] = 0;
	res[1] = 1;
	for (int i = 2; i <= n; i++)
	{
		res[2] = res[1] + res[0];
		res[0] = res[1];
		res[1] = res[2];
	}
	return res[1];
}
int main(int argc, char const *argv[])
{
	int n;
	cout << "Enter n: ";
	cin >> n;
	cout << "Fibonacci number is ";
	cout << fib(n) << endl;
	return 0;
}

Fibonacci Top Down

#include 
using namespace std;
int arr[1000000];
int fib(int n)
{
	if (arr[n] == -1)
	{
		if (n <= 1)
			arr[n] = n;
		else
			arr[n] = fib(n - 1) + fib(n - 2);
	}
	return arr[n];
}
int main(int argc, char const *argv[])
{
	int n;
	cout << "Enter n: ";
	cin >> n;
	for (int i = 0; i < n + 1; ++i)
	{
		arr[i] = -1;
	}
	cout << "Fibonacci number is " << fib(n) << endl;
	return 0;
}

Floyd Warshall

#include 
#include 
#include 

using namespace std;

//Wrapper class for storing a graph
class Graph
{
public:
	int vertexNum;
	int **edges;

	//Constructs a graph with V vertices and E edges
	Graph(int V)
	{
		this->vertexNum = V;
		this->edges = (int **)malloc(V * sizeof(int *));
		for (int i = 0; i < V; i++)
		{
			this->edges[i] = (int *)malloc(V * sizeof(int));
			for (int j = 0; j < V; j++)
				this->edges[i][j] = INT_MAX;
			this->edges[i][i] = 0;
		}
	}

	//Adds the given edge to the graph
	void addEdge(int src, int dst, int weight)
	{
		this->edges[src][dst] = weight;
	}
};

//Utility function to print distances
void print(int dist[], int V)
{
	cout << "\nThe Distance matrix for Floyd - Warshall" << endl;
	for (int i = 0; i < V; i++)
	{
		for (int j = 0; j < V; j++)
		{

			if (dist[i * V + j] != INT_MAX)
				cout << dist[i * V + j] << "\t";
			else
				cout << "INF"
					 << "\t";
		}
		cout << endl;
	}
}

//The main function that finds the shortest path from a vertex
//to all other vertices using Floyd-Warshall Algorithm.
void FloydWarshall(Graph graph)
{
	int V = graph.vertexNum;
	int dist[V][V];

	//Initialise distance array
	for (int i = 0; i < V; i++)
		for (int j = 0; j < V; j++)
			dist[i][j] = graph.edges[i][j];

	//Calculate distances
	for (int k = 0; k < V; k++)
		//Choose an intermediate vertex

		for (int i = 0; i < V; i++)
			//Choose a source vertex for given intermediate

			for (int j = 0; j < V; j++)
				//Choose a destination vertex for above source vertex

				if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX && dist[i][k] + dist[k][j] < dist[i][j])
					//If the distance through intermediate vertex is less than direct edge then update value in distance array
					dist[i][j] = dist[i][k] + dist[k][j];

	//Convert 2d array to 1d array for print
	int dist1d[V * V];
	for (int i = 0; i < V; i++)
		for (int j = 0; j < V; j++)
			dist1d[i * V + j] = dist[i][j];

	print(dist1d, V);
}

//Driver Function
int main()
{
	int V, E;
	int src, dst, weight;
	cout << "Enter number of vertices: ";
	cin >> V;
	cout << "Enter number of edges: ";
	cin >> E;
	Graph G(V);
	for (int i = 0; i < E; i++)
	{
		cout << "\nEdge " << i + 1 << "\nEnter source: ";
		cin >> src;
		cout << "Enter destination: ";
		cin >> dst;
		cout << "Enter weight: ";
		cin >> weight;
		G.addEdge(src, dst, weight);
	}
	FloydWarshall(G);

	return 0;
}

Longest Common Subsequence

//Longest common subsequence - Dynamic Programming
#include 
using namespace std;

void Print(int trace[20][20], int m, int n, string a)
{
    if (m == 0 || n == 0)
    {
        return;
    }
    if (trace[m][n] == 1)
    {
        Print(trace, m - 1, n - 1, a);
        cout << a[m - 1];
    }
    else if (trace[m][n] == 2)
    {
        Print(trace, m - 1, n, a);
    }
    else if (trace[m][n] == 3)
    {
        Print(trace, m, n - 1, a);
    }
}

int lcs(string a, string b)
{
    int m = a.length(), n = b.length();
    int res[m + 1][n + 1];
    int trace[20][20];

    // fills up the arrays with zeros.
    for (int i = 0; i < m + 1; i++)
    {
        for (int j = 0; j < n + 1; j++)
        {
            res[i][j] = 0;
            trace[i][j] = 0;
        }
    }

    for (int i = 0; i < m + 1; ++i)
    {
        for (int j = 0; j < n + 1; ++j)
        {
            if (i == 0 || j == 0)
            {
                res[i][j] = 0;
                trace[i][j] = 0;
            }

            else if (a[i - 1] == b[j - 1])
            {
                res[i][j] = 1 + res[i - 1][j - 1];
                trace[i][j] = 1; // 1 means trace the matrix in upper left diagonal direction.
            }
            else
            {
                if (res[i - 1][j] > res[i][j - 1])
                {
                    res[i][j] = res[i - 1][j];
                    trace[i][j] = 2; // 2 means trace the matrix in upwards direction.
                }
                else
                {
                    res[i][j] = res[i][j - 1];
                    trace[i][j] = 3; //  means trace the matrix in left direction.
                }
            }
        }
    }
    Print(trace, m, n, a);
    return res[m][n];
}

int main()
{
    string a, b;
    cin >> a >> b;
    cout << lcs(a, b);
    return 0;
}

Longest Increasing Subsequence

//Program to calculate length of longest increasing subsequence in an array
// in O(n log n)
// tested on : https://cses.fi/problemset/task/1145/

#include 

using namespace std;
int LIS(int arr[], int n)
{
    set < int > active; // The current built LIS.
    active.insert(arr[0]);
    // Loop through every element.
    for (int i = 1; i < n; ++i)
    {
        auto get = active.lower_bound(arr[i]);
        if (get == active.end())
	{
            active.insert(arr[i]);
        } // current element is the greatest so LIS increases by 1.
        else
	{
            int val = * get; // we find the position where arr[i] will be in the LIS. If it is in the LIS already we do nothing
            if (val > arr[i])
	    {
                // else we remove the bigger element and add a smaller element (which is arr[i]) and continue;
                active.erase(get);
                active.insert(arr[i]);
            }
        }
    }
    return active.size(); // size of the LIS.
}
int main(int argc, char const * argv[])
{
    int n;
    cout << "Enter size of array: ";
    cin >> n;
    int a[n];
    cout << "Enter array elements: ";
    for (int i = 0; i < n; ++i)
    {
        cin >> a[i];
    }
    cout << LIS(a, n) << endl;
    return 0;
}

Matrix Chain Multiplication

#include 
#include 
using namespace std;

#define MAX 10

// dp table to store the solution for already computed sub problems
int dp[MAX][MAX];

// Function to find the most efficient way to multiply the given sequence of matrices
int MatrixChainMultiplication(int dim[], int i, int j)
{
	// base case: one matrix
	if (j <= i + 1)
		return 0;

	// stores minimum number of scalar multiplications (i.e., cost)
	// needed to compute the matrix M[i+1]...M[j] = M[i..j]
	int min = INT_MAX;

	// if dp[i][j] is not calculated (calculate it!!)

	if (dp[i][j] == 0)
	{
		// take the minimum over each possible position at which the
		// sequence of matrices can be split

		for (int k = i + 1; k <= j - 1; k++)
		{
			// recur for M[i+1]..M[k] to get a i x k matrix
			int cost = MatrixChainMultiplication(dim, i, k);

			// recur for M[k+1]..M[j] to get a k x j matrix
			cost += MatrixChainMultiplication(dim, k, j);

			// cost to multiply two (i x k) and (k x j) matrix
			cost += dim[i] * dim[k] * dim[j];

			if (cost < min)
				min = cost; // store the minimum cost
		}
		dp[i][j] = min;
	}

	// return min cost to multiply M[j+1]..M[j]
	return dp[i][j];
}

// main function
int main()
{
	// Matrix i has Dimensions dim[i-1] & dim[i] for i=1..n
	// input is 10 x 30 matrix, 30 x 5 matrix, 5 x 60 matrix
	int dim[] = {10, 30, 5, 60};
	int n = sizeof(dim) / sizeof(dim[0]);

	// Function Calling: MatrixChainMultiplications(dimensions_array, starting, ending);

	cout << "Minimum cost is " << MatrixChainMultiplication(dim, 0, n - 1) << "\n";

	return 0;
}

Armstrong Number

// Program to check whether a number is an armstrong number or not
#include 

using std::cout;
using std::cin;

int main() {
  int n, k, d, s = 0;
  cout << "Enter a number:";
  cin >> n;
  k = n;
  while (k != 0) {
    d = k % 10;
    s += d * d * d;
    k /= 10;
  }
  if (s == n)
    cout << n << "is an armstrong number";
  else
    cout << n << "is not an armstrong number";
}

Kadane

#include
#include

int maxSubArraySum(int a[], int size) {
    int max_so_far = INT_MIN, max_ending_here = 0;

    for (int i = 0; i < size; i++) {
        max_ending_here = max_ending_here + a[i];
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;

        if (max_ending_here < 0)
            max_ending_here = 0;
    }
    return max_so_far;
}


int main() {
    int n, i;
    std::cout << "Enter the number of elements \n";
    std::cin >> n;
    int a[n];  // NOLINT
    for (i = 0; i < n; i++) {
        std::cin >> a[i];
    }
    int max_sum = maxSubArraySum(a, n);
    std::cout << "Maximum contiguous sum is " << max_sum;
    return 0;
}

Longest Common String

#include 
using namespace std;

int max(int a,int b)
{
    return (a > b) ? a : b;
}

int main()
{
    char str1[]="DEFBCD";
    char str2[]="ABDEFJ";
    int i,j,k;
    int n=strlen(str1)+1;
    int m=strlen(str2)+1;
    //cout<
    int a[m][n];

    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            if(i==0 || j==0)
                a[i][j]=0;

            else if(str1[i-1] == str2[j-1])
                    a[i][j]=a[i-1][j-1]+1;

            else
                a[i][j]=0;
        }
    }


/*for(i=0;i


int ma=-1;
int indi,indj;
for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            if(a[i][j]>ma)
            {
                ma=a[i][j];
                indi=i;
                indj=j;
            }
        }
    }

    cout<<str1<<"\n";
    cout<<str2<<"\n";

    cout<<"longest string size = "<<ma/*<<" "<<<"\n";
    for(i=indi-3;i<indi;i++)
        cout<<str1[i];
    cout<<"\n";
}

Searching of Element in Dynamic Array

/*
*this program is use to find any elemet in any row with variable array size
*aplication of pointer is use in it
*important point start from here to:
*the index value of array can be go to 1 to 100000
*check till array[1000]
*end here
*how to work example:
**Question:
***number of array 2
***quarry 3
***array 1 is {1 2 3 4 5}
***array 2 is {6 7}
****i) what is 2nd element in 1st array
****ii) what is 1st element in 2nd array
****iii) what is 5th element in 1st array
*****output:
*****Enter Number of array you want to Store : 2
*****Enter Number of Question or Quary you want to do Related to Array : 3
*****Enter number of element in 1 rows : 5
*****Enter the element of Array 1 2 3 4 5
*****Enter number of element in 2 rows : 2
*****Enter the element of Array 6 7
*****enter the number of row which element You want to find : 1
*****enter the position of element which You want to find : 2
*****The element is 2
*****enter the number of row which element You want to find : 2
*****enter the position of element which You want to find : 1
*****The element is 6
*****enter the number of row which element You want to find : 1
*****enter the position of element which You want to find : 5
*****The element is 5
*/
#include 

// this is main fuction
// ***
int main() {
    int64_t r, mr = 0, x, q, i, z;
    std::cout << "Enter Number of array you want to Store :";
    std::cin >> x;
    std::cout << "Enter Number of ";
    std::cout << "Question or Quary you ";
    std::cout << "want to do Related to Array :";
    std::cin >> q;
    // create a Array in run time because use can
    // change the size of each array which he/she is going to store
    // create a 2D array
    int** ar = new int* [x]();
    // this for loop is use for entering different variable size array
    // ***
    for (r = 0; r < x; r++) {
        std::cout << "Enter number of element in " << r + 1 << " rows :";
        std::cin >> mr;
        // creating a 1D array
        int* ac = new int[mr]();
        std::cout << "Enter the element of Array ";
        // this for loop is use for storing values in array
        // ***
        for (i = 0; i < mr; i++) {
            // entering the value of rows in array in Horizontal
            std::cin >> ac[i];
        }
        // Change the position of Array so that new arrays entery will be done
        ar[r] = ac;
    }
    // this for loop is use for display result of querry
    // ***
    for (z = 0; z < q; z++) {
        int64_t r1 = 0, q1 = 0;
        std::cout << "enter the number of row which element you want to find :";
        std::cin >> r1;
        r1 = r1 - 1;
        std::cout << "enter the position of element which you want to find :";
        std::cin >> q1;
        q1 = q1 - 1;
        // use this to find desire position of element in desire array
        std::cout <<"The element is "<< ar[r1][q1] <<std::endl;
    }
}

Tree Height

// C++ Program to find height of the tree using bottom-up dynamic programming.

/*
 * Given a rooted tree with node 1.
 * Task is to find the height of the tree.
 * Example: -
 * 4
 * 1 2
 * 1 3
 * 2 4
 * which can be represented as                 
 *   1                      
 *  / \                     
 * 2   3                    
 * |                        
 * 4            
 * 
 * Height of the tree : - 2
*/

#include
#include

// global declarations
// no of nodes max limit.
const int MAX = 1e5;
// adjacency list
std::vector<int> adj[MAX];
std::vector<bool> visited;
std::vector<int> dp;

void depth_first_search(int u) {
    visited[u] = true;
    int child_height = 1;
    for (int v : adj[u]) {
        if (!visited[v]) {
            depth_first_search(v);

            // select maximum sub-tree height from all children.
            child_height = std::max(child_height, dp[v]+1);
        }
    }
    // assigned the max child height to current visited node.
    dp[u] = child_height;
}

int main() {
    // number of nodes
    int number_of_nodes;
    std::cout << "Enter number of nodes of the tree : " << std::endl;
    std::cin >> number_of_nodes;

    // u, v denotes an undirected edge of tree.
    int u, v;
    // Tree contains exactly n-1 edges where n denotes the number of nodes.
    std::cout << "Enter edges of the tree : " << std::endl;
    for (int i = 0; i < number_of_nodes - 1; i++) {
        std::cin >> u >> v;
        // undirected tree u -> v and v -> u.
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    // initialize all nodes as unvisited.
    visited.assign(number_of_nodes+1, false);
    // initialize depth of all nodes to 0.
    dp.assign(number_of_nodes+1, 0);
    // function call which will initialize the height of all nodes.
    depth_first_search(1);
    std::cout << "Height of the Tree : " << dp[1] << std::endl;
}

字符串算法

Brute Force String Searching

#include  
#include  
#include  

using std::string;

int brute_force(string text, string pattern);
std::vector<std::vector<string>> test_set  =   {
    // {text, pattern, expected output}
     {"a", "aa", "-1"},
     {"a", "a", "0"},
     {"ba", "b", "0"},
     {"bba", "bb", "0"},
     {"bbca", "c", "2"},
     {"ab", "b", "1"}
};

int main() {
    for  (size_t i  =  0 ;  i < test_set.size();  i++) {
        int output  =  brute_force(test_set[i][0],  test_set[i][1]);
        if (std::to_string(output)  ==  test_set[i][2])
            std::cout  <<  "success\n";
        else
            std::cout  <<  "failure\n";
    }
    return 0;
}

/*
 *@description    Find a pattern in a string by comparing the pattern
 *                to every substring.
 *@param text     Any string that might contain the pattern.
 *@param pattern  String that we are searching for.
 *@return       Index where the pattern starts in the text or
 *                -1 if the pattern was not found.
 */

int brute_force(string text, string pattern) {
    size_t pat_l  =  pattern.length();
    size_t txt_l  =  text.length();
    int index  =  -1;
    if (pat_l  <=  txt_l) {
        for  (size_t i = 0;  i < txt_l-pat_l+1; i++) {
            string s  =  text.substr(i, pat_l);
            if (s  ==  pattern) {
                index  =  i;
                break;
            }
        }
    }
    return index;
}

Kunth Morris Pratt

/*
    The Knuth-Morris-Pratt Algorithm for finding a pattern within a piece of text
    with complexity O(n + m)
    1) Preprocess pattern to identify any suffixes that are identical to prefixes
        This tells us where to continue from if we get a mismatch between a character in our pattern
        and the text.
    2) Step through the text one character at a time and compare it to a character in the pattern
        updating our location within the pattern if necessary
*/

#include
#include
#include
using namespace std;
vector<int> getFailureArray(string pattern){
    int pattern_length=pattern.size();
    vector<int>failure(pattern_length+1);
    failure[0]=-1;
    int j=-1;
    for(int i=0; i<pattern_length; i++){
        while(j!=-1&&pattern[j]!=pattern[i]){
            j=failure[j];
        }
        j++;
        failure[i+1]=j;
    }
    return failure;
}
bool kmp(string pattern,string text){
    int text_length=text.size(),pattern_length=pattern.size();
    vector<int>failure=getFailureArray(pattern);
    int k=0;
    for(int  j=0; j<text_length; j++){
        while(k!=-1&&pattern[k]!=text[j]){
            k=failure[k];
        }
        k++;
        if(k==pattern_length)return true;
    }
    return false;
}

int main()
{   
   
    string text="alskfjaldsabc1abc1abc12k23adsfabcabc";
    string pattern="abc1abc12l";
    if(kmp(pattern,text)==true){
        cout<<"Found"<<endl;
    }
    else{
        cout<<"Not Found"<<endl;
    }
    text="abcabc";
    pattern="bca";
    if(kmp(pattern,text)==true){
        cout<<"Found"<<endl;
    }
    else{
        cout<<"Not Found"<<endl;
    }
    return 0;
}

数学相关算法

Binary Exponent

计算 a b a^b ab

#include
/*
 * Calculate a^b in O(log(b)) by converting b to a binary number.
 * Binary exponentiation is also known as exponentiation by squaring.
 * NOTE : This is a far better approach compared to naive method which provide O(b) operations.
 * Example:
 * 10 in base 2 is 1010.
 * 2^10 = 2^(1010) = 2^8 * 2^2
 * 2^1 = 2
 * 2^2 = (2^1)^2 = 2^2 = 4
 * 2^4 = (2^2)^2 = 4^2 = 16
 * 2^8 = (2^4)^2 = 16^2 = 256
 * Hence to calculate 2^10 we only need to multiply 2^8 and 2^2 skipping 2^1 and 2^4.
*/

/// Recursive function to calculate exponent in O(log(n)) using binary exponent.
int binExpo(int a, int b) {
    if (b == 0) {
        return 1;
    }
    int res = binExpo(a, b/2);
    if (b%2) {
        return res*res*a;
    } else {
        return res*res;
    }
}

/// Iterative function to calculate exponent in O(log(n)) using binary exponent.
int binExpo_alt(int a, int b) {
    int res = 1;
    while (b > 0) {
        if (b%2) {
            res = res*a;
        }
        a = a*a;
        b /= 2;
    }
    return res;
}

int main() {
    int a, b;
    /// Give two numbers a, b
    std::cin >> a >> b;
    if (a == 0 && b == 0) {
        std::cout << "Math error" << std::endl;
    } else if (b < 0) {
        std::cout << "Exponent must be positive !!" << std::endl;
    } else {
        int resRecurse = binExpo(a, b);
        /// int resIterate = binExpo_alt(a, b);

        /// Result of a^b (where '^' denotes exponentiation)
        std::cout << resRecurse << std::endl;
        /// std::cout << resIterate << std::endl;
    }
}

Eulers Totient Function

计算欧拉函数 φ \varphi φ

#include

/*
 * Euler Totient Function is also known as phi function.
 * phi(n) = phi(p1^a1).phi(p2^a2)...
 * where p1, p2,... are prime factors of n.
 * 3 Euler's properties:
 * 1. phi(prime_no) = prime_no-1
 * 2. phi(prime_no^k) = (prime_no^k - prime_no^(k-1))
 * 3. phi(a,b) = phi(a). phi(b) where a and b are relative primes.
 * Applying this 3 properties on the first equation.
 * phi(n) = n. (1-1/p1). (1-1/p2). ...
 * where p1,p2... are prime factors.
 * Hence Implementation in O(sqrt(n)).
 * phi(100) = 40
 * phi(1) = 1
 * phi(17501) = 15120
 * phi(1420) = 560
 */

// Function to caculate Euler's totient phi
int phiFunction(int n) {
    int result = n;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            while (n % i == 0) {
                n /= i;
            }
            result -= result / i;
        }
    }
    if (n > 1) result -= result / n;
    return result;
}

int main() {
    int n;
    std::cin >> n;
    std::cout << phiFunction(n);
}

Factorial

计算质因数分解

#include

// function to find factorial of given number
unsigned int factorial(unsigned int n) {
    if (n == 0)
        return 1;
    return n * factorial(n - 1);
}

// Driver code
int main() {
    int num = 5;
    std::cout << "Factorial of " << num << " is " << factorial(num)
              << std::endl;
    return 0;
}

Fast Power

计算 a b a^b ab

#include 
#include 
#include 
#include 
#include 
#include 

/*
    Program that computes a^b in O(logN) time.
    It is based on formula that:
        case1) if b is even: a^b = a^(b/2) * a^(b/2) = (a^(b/2))ˆ2
        case2) if b is odd: a^b = a^((b-1)/2) * a^((b-1)/2) * a = (a^((b-1)/2))^2 * a
    We can compute a^b recursively using above algorithm.
*/

double fast_power_recursive(int64_t a, int64_t b) {
    // negative power. a^b = 1 / (a^-b)
    if (b < 0)
        return 1.0 / fast_power_recursive(a, -b);

    if (b == 0) return 1;
    int64_t bottom = fast_power_recursive(a, b >> 1);
    // Since it is integer division b/2 = (b-1)/2 where b is odd.
    // Therefore, case2 is easily solved by integer division.

    int64_t result;
    if ((b & 1) == 0)  // case1
        result = bottom * bottom;
    else  // case2
        result = bottom * bottom * a;
    return result;
}

/*
    Same algorithm with little different formula.
    It still calculates in O(logN)
*/
double fast_power_linear(int64_t a, int64_t b) {
    // negative power. a^b = 1 / (a^-b)
    if (b < 0)
        return 1.0 / fast_power_linear(a, -b);

    double result = 1;
    while (b) {
        if (b & 1) result = result * a;
        a = a * a;
        b = b >> 1;
    }
    return result;
}

int main() {
    std::srand(time(NULL));
    std::ios_base::sync_with_stdio(false);

    std::cout << "Testing..." << std::endl;
    for (int i = 0; i < 20; i++) {
        unsigned int *rand1, *rand2;
        int a = rand_r(rand1) % 20 - 10;
        int b = rand_r(rand2) % 20 - 10;
        std::cout << std::endl << "Calculating " << a << "^" << b << std::endl;
        assert(fast_power_recursive(a, b) == std::pow(a, b));
        assert(fast_power_linear(a, b) == std::pow(a, b));

        std::cout << "------ " << a << "^" << b << " = "<<
            fast_power_recursive(a, b) << std::endl;
    }

    int64_t a, b;
    std::cin >> a >> b;

    std::cout << a << "^" << b << " = "<<
        fast_power_recursive(a, b) << std::endl;

    std::cout << a << "^" << b << " = "<<
        fast_power_linear(a, b) << std::endl;

    return 0;
}

Greastest Common Divisor

计算GCD

#include 

// Recursive function to return gcd of a and b
int gcd(int a, int b) {
    // Everything divides 0
    if (a == 0)
       return b;
    if (b == 0)
       return a;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

// Driver program to test above function
int main() {
    int a = 98, b = 56;
    std::cout << "GCD of " << a << " and " << b << " is " << gcd(a, b);
    return 0;
}

Greastest Common Divisor Euclidean

计算GCD

#include 
#include 
#include 

// will find the greatest common denominator of two ints integers
// Euclidean algorithm can be found here
// https://en.wikipedia.org/wiki/Euclidean_algorithm
int gcd(int num1, int num2) {
    if (num1 <= 0 | num2 <= 0) {
        throw std::domain_error("Euclidean algorithm domain is for ints > 0");
    }

    if (num1 == num2) {
        return num1;
    }

    int base_num = 0;
    int previous_remainder = 1;

    if (num1 > num2) {
        base_num = num1;
        previous_remainder = num2;
    } else {
        base_num = num2;
        previous_remainder = num1;
    }

    while ((base_num % previous_remainder) != 0) {
        int old_base = base_num;
        base_num = previous_remainder;
        previous_remainder = old_base % previous_remainder;
    }

    return previous_remainder;
}

int main() {
    std::cout << "gcd of 120,7 is " << (gcd(120, 7)) << std::endl;
    try {
        std::cout << "gcd of -120,10 is " << gcd(-120, 10) << std::endl;
    } catch (const std::domain_error &e) {
        std::cout << "Error handling was successful" << std::endl;
    }
    std::cout << "gcd of 312,221 is " << (gcd(312, 221)) << std::endl;
    std::cout << "gcd of 289,204 is " << (gcd(289, 204)) << std::endl;

    return 0;
}

Number of Positive Divisors

计算质因子数量

#include
#include

/**
 * This algorithm use the prime factorization approach.
 * Any number can be written in multiplication of its prime factors.
 * Let N = P1^E1 * P2^E2 ... Pk^Ek
 * Therefore. number-of-divisors(N) = (E1+1) * (E2+1) ... (Ek+1).
 * Where P1, P2 ... Pk are prime factors and E1, E2 ... Ek are exponents respectively.
 *
 * Example:-
 * N = 36
 * 36 = (3^2 * 2^2)
 * number_of_positive_divisors(36) = (2+1) * (2+1) = 9.
 * list of positive divisors of 36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
 *
 * Similarly if N is -36 at that time number of positive divisors remain same.
 *
 * Example:-
 * N = -36
 * -36 = -1 * (3^2 * 2^2)
 * number_of_positive_divisors(-36) = (2+1) * (2+1) = 9.
 * list of positive divisors of -36 = 1, 2, 3, 4, 6, 9, 12, 18, 36.
 *
**/

int number_of_positive_divisors(int n) {
    std::vector<int> prime_exponent_count;
    for (int i=2; i*i <= n; i++) {
        int prime_count = 0;
        while (n % i == 0) {
            prime_count += 1;
            n /= i;
        }
        if (prime_count != 0) {
            prime_exponent_count.push_back(prime_count);
        }
    }
    if (n > 1) {
        prime_exponent_count.push_back(1);
    }

    int divisors_count = 1;

    for (int i=0; i < prime_exponent_count.size(); i++) {
        divisors_count = divisors_count * (prime_exponent_count[i]+1);
    }

    return divisors_count;
}

int main() {
    int n;
    std::cin >> n;
    if (n < 0) {
        n = -n;
    }
    if (n == 0) {
        std::cout << "All non-zero numbers are divisors of 0 !" << std::endl;
    } else {
        std::cout << "Number of positive divisors is : ";
        std::cout << number_of_positive_divisors(n) << std::endl;
    }
}

Power for Huge Numbers

计算 a b a^b ab

#include 
using namespace std;

// Maximum number of digits in output
// x^n where 1 <= x, n <= 10000 and overflow may happen
#define MAX 100000

// This function multiplies x
// with the number represented by res[].
// res_size is size of res[] or
// number of digits in the number
// represented by res[]. This function
// uses simple school mathematics
// for multiplication.
// This function may value of res_size
// and returns the new value of res_size
int multiply(int x, int res[], int res_size)
{

	// Initialize carry
	int carry = 0;

	// One by one multiply n with
	// individual digits of res[]
	for (int i = 0; i < res_size; i++)
	{
		int prod = res[i] * x + carry;

		// Store last digit of
		// 'prod' in res[]
		res[i] = prod % 10;

		// Put rest in carry
		carry = prod / 10;
	}

	// Put carry in res and
	// increase result size
	while (carry)
	{
		res[res_size] = carry % 10;
		carry = carry / 10;
		res_size++;
	}
	return res_size;
}

// This function finds
// power of a number x
void power(int x, int n)
{

	//printing value "1" for power = 0
	if (n == 0)
	{
		cout << "1";
		return;
	}

	int res[MAX];
	int res_size = 0;
	int temp = x;

	// Initialize result
	while (temp != 0)
	{
		res[res_size++] = temp % 10;
		temp = temp / 10;
	}

	// Multiply x n times
	// (x^n = x*x*x....n times)
	for (int i = 2; i <= n; i++)
		res_size = multiply(x, res, res_size);

	cout << x << "^" << n << " = ";
	for (int i = res_size - 1; i >= 0; i--)
		cout << res[i];
}

// Driver program
int main()
{
	int exponent, base;
	printf("Enter base ");
	scanf("%id \n", &base);
	printf("Enter exponent ");
	scanf("%id", &exponent);
	power(base, exponent);
	return 0;
}

Prime Factorization

质数检测

#include 
#include 
#include 
using namespace std;

// Declaring variables for maintaing prime numbers and to check whether a number is prime or not
bool isprime[1000006];
vector<int> prime_numbers;
vector<pair<int, int>> factors;

// Calculating prime number upto a given range
void SieveOfEratosthenes(int N)
{
    // initializes the array isprime
    memset(isprime, true, sizeof isprime);

    for (int i = 2; i <= N; i++)
    {
        if (isprime[i])
        {
            for (int j = 2 * i; j <= N; j += i)
                isprime[j] = false;
        }
    }

    for (int i = 2; i <= N; i++)
    {
        if (isprime[i])
            prime_numbers.push_back(i);
    }
}

// Prime factorization of a number
void prime_factorization(int num)
{

    int number = num;

    for (int i = 0; prime_numbers[i] <= num; i++)
    {
        int count = 0;

        // termination condition
        if (number == 1)
        {
            break;
        }

        while (number % prime_numbers[i] == 0)
        {
            count++;
            number = number / prime_numbers[i];
        }

        if (count)
            factors.push_back(make_pair(prime_numbers[i], count));
    }
}

/*
    I added a simple UI.
*/
int main()
{
    int num;
    cout << "\t\tComputes the prime factorization\n\n";
    cout << "Type in a number: ";
    cin >> num;

    SieveOfEratosthenes(num);

    prime_factorization(num);

    // Prime factors with their powers in the given number in new line
    for (auto it : factors)
    {
        cout << it.first << " " << it.second << endl;
    }

    return 0;
}

Prime Numbers

质数检测

#include 
#include 

std::vector<int> primes(int max) {
    max++;
    std::vector<int> res;
    std::vector<bool> numbers(max, false);
    for (int i = 2; i < max; i++) {
        if (!numbers[i]) {
            for (int j = i; j < max; j += i)
                numbers[j] = true;
            res.push_back(i);
        }
    }
    return res;
}

int main() {
    std::cout << "Calculate primes up to:\n>> ";
    int n;
    std::cin >> n;
    std::vector<int> ans = primes(n);
    for (int i = 0; i < ans.size(); i++)
        std::cout << ans[i] << ' ';
    std::cout << std::endl;
}

Primes Up to 10^8

质数检测

#include
#include 

char prime[100000000];

void Sieve(int64_t n) {
    memset(prime, '1', sizeof(prime));  // intitize '1' to every index
    prime[0] = '0';  // 0 is not prime
    prime[1] = '0';  // 1 is not prime
    for (int p = 2; p * p <= n; p++) {
        if (prime[p] == '1') {
            for (int i = p * p; i <= n; i += p)
                prime[i] = '0';  // set all multiples of p to false
        }
    }
}


int main() {
    Sieve(100000000);
    int64_t n;
    std::cin >> n;  // 10006187
    if (prime[n] == '1')
        std::cout << "YES\n";
    else
        std::cout << "NO\n";
}

Sieve of Eratosthenes

找质数

/*
 * Sieve of Eratosthenes is an algorithm to find the primes 
 * that is between 2 to N (as defined in main).
 *
 * Time Complexity  : O(N * log N)
 * Space Complexity : O(N)
 */

#include 
using namespace std;

#define MAX 10000000

int isprime[MAX];

/*
 * This is the function that finds the primes and eliminates 
 * the multiples.
 */
void sieve(int N)
{
    isprime[0] = 0;
    isprime[1] = 0;
    for (int i = 2; i <= N; i++)
    {
        if (isprime[i])
        {
            for (int j = i * 2; j <= N; j += i)
            {
                isprime[j] = 0;
            }
        }
    }
}

/*
 * This function prints out the primes to STDOUT
 */
void print(int N)
{
    for (int i = 1; i <= N; i++)
    {
        if (isprime[i] == 1)
        {
            cout << i << ' ';
        }
    }
    cout << '\n';
}

/*
 * NOTE: This function is important for the 
 * initialization of the array.
 */
void init()
{
    for (int i = 1; i < MAX; i++)
    {
        isprime[i] = 1;
    }
}

int main()
{
    int N = 100;
    init();
    sieve(N);
    print(N);
}

数据结构

Datastructures

AVLtree

#include 
#include 

using namespace std;

typedef struct node
{
	int data;
	int height;
	struct node *left;
	struct node *right;
} node;

int max(int a, int b)
{
	return a > b ? a : b;
}

// Returns a new Node

node *createNode(int data)
{
	node *nn = new node();
	nn->data = data;
	nn->height = 0;
	nn->left = NULL;
	nn->right = NULL;
	return nn;
}

// Returns height of tree

int height(node *root)
{
	if (root == NULL)
		return 0;
	return 1 + max(height(root->left), height(root->right));
}

// Returns difference between height of left and right subtree

int getBalance(node *root)
{
	return height(root->left) - height(root->right);
}

// Returns Node after Right Rotation

node *rightRotate(node *root)
{
	node *t = root->left;
	node *u = t->right;
	t->right = root;
	root->left = u;
	return t;
}

// Returns Node after Left Rotation

node *leftRotate(node *root)
{
	node *t = root->right;
	node *u = t->left;
	t->left = root;
	root->right = u;
	return t;
}

// Returns node with minimum value in the tree

node *minValue(node *root)
{
	if (root->left == NULL)
		return root;
	return minValue(root->left);
}

// Balanced Insertion

node *insert(node *root, int item)
{
	node *nn = createNode(item);
	if (root == NULL)
		return nn;
	if (item < root->data)
		root->left = insert(root->left, item);
	else
		root->right = insert(root->right, item);
	int b = getBalance(root);
	if (b > 1)
	{
		if (getBalance(root->left) < 0)
			root->left = leftRotate(root->left); // Left-Right Case
		return rightRotate(root);				 // Left-Left Case
	}
	else if (b < -1)
	{
		if (getBalance(root->right) > 0)
			root->right = rightRotate(root->right); // Right-Left Case
		return leftRotate(root);					// Right-Right Case
	}
	return root;
}

// Balanced Deletion

node *deleteNode(node *root, int key)
{
	if (root == NULL)
		return root;
	if (key < root->data)
		root->left = deleteNode(root->left, key);
	else if (key > root->data)
		root->right = deleteNode(root->right, key);

	else
	{
		// Node to be deleted is leaf node or have only one Child
		if (!root->right)
		{
			node *temp = root->left;
			delete (root);
			root = NULL;
			return temp;
		}
		else if (!root->left)
		{
			node *temp = root->right;
			delete (root);
			root = NULL;
			return temp;
		}
		// Node to be deleted have both left and right subtrees
		node *temp = minValue(root->right);
		root->data = temp->data;
		root->right = deleteNode(root->right, temp->data);
	}
	// Balancing Tree after deletion
	return root;
}

// LevelOrder (Breadth First Search)

void levelOrder(node *root)
{
	queue<node *> q;
	q.push(root);
	while (!q.empty())
	{
		root = q.front();
		cout << root->data << " ";
		q.pop();
		if (root->left)
			q.push(root->left);
		if (root->right)
			q.push(root->right);
	}
}

int main()
{
	// Testing AVL Tree
	node *root = NULL;
	int i;
	for (i = 1; i <= 7; i++)
		root = insert(root, i);
	cout << "LevelOrder: ";
	levelOrder(root);
	root = deleteNode(root, 1); // Deleting key with value 1
	cout << "\nLevelOrder: ";
	levelOrder(root);
	root = deleteNode(root, 4); // Deletin key with value 4
	cout << "\nLevelOrder: ";
	levelOrder(root);
	return 0;
}

Binary Search Tree

#include 
using namespace std;

struct node
{
	int val;
	node *left;
	node *right;
};

struct queue
{
	node *t[100];
	int front;
	int rear;
};

queue q;

void enqueue(node *n)
{
	q.t[q.rear++] = n;
}

node *dequeue()
{
	return (q.t[q.front++]);
}

void Insert(node *n, int x)
{
	if (x < n->val)
	{
		if (n->left == NULL)
		{
			node *temp = new node;
			temp->val = x;
			temp->left = NULL;
			temp->right = NULL;
			n->left = temp;
		}
		else
		{
			Insert(n->left, x);
		}
	}
	else
	{
		if (n->right == NULL)
		{
			node *temp = new node;
			temp->val = x;
			temp->left = NULL;
			temp->right = NULL;
			n->left = temp;
		}
		else
		{
			Insert(n->right, x);
		}
	}
}

int findMaxInLeftST(node *n)
{
	while (n->right != NULL)
	{
		n = n->right;
	}
	return n->val;
}

void Remove(node *p, node *n, int x)
{
	if (n->val == x)
	{
		if (n->right == NULL && n->left == NULL)
		{
			if (x < p->val)
			{
				p->right = NULL;
			}
			else
			{
				p->left = NULL;
			}
		}
		else if (n->right == NULL)
		{
			if (x < p->val)
			{
				p->right = n->left;
			}
			else
			{
				p->left = n->left;
			}
		}
		else if (n->left == NULL)
		{
			if (x < p->val)
			{
				p->right = n->right;
			}
			else
			{
				p->left = n->right;
			}
		}
		else
		{
			int y = findMaxInLeftST(n->left);
			n->val = y;
			Remove(n, n->right, y);
		}
	}
	else if (x < n->val)
	{
		Remove(n, n->left, x);
	}
	else
	{
		Remove(n, n->right, x);
	}
}

void BFT(node *n)
{
	if (n != NULL)
	{
		cout << n->val << "  ";
		enqueue(n->left);
		enqueue(n->right);
		BFT(dequeue());
	}
}

void Pre(node *n)
{
	if (n != NULL)
	{
		cout << n->val << "  ";
		Pre(n->left);
		Pre(n->right);
	}
}

void In(node *n)
{
	if (n != NULL)
	{
		In(n->left);
		cout << n->val << "  ";
		In(n->right);
	}
}

void Post(node *n)
{
	if (n != NULL)
	{
		Post(n->left);
		Post(n->right);
		cout << n->val << "  ";
	}
}

int main()
{
	q.front = 0;
	q.rear = 0;
	int value;
	int ch;
	node *root = new node;
	cout << "\nEnter the value of root node :";
	cin >> value;
	root->val = value;
	root->left = NULL;
	root->right = NULL;
	do
	{
		cout << "\n1. Insert";
		cout << "\n2. Delete";
		cout << "\n3. Breadth First";
		cout << "\n4. Preorder Depth First";
		cout << "\n5. Inorder Depth First";
		cout << "\n6. Postorder Depth First";

		cout << "\nEnter Your Choice : ";
		cin >> ch;
		int x;
		switch (ch)
		{
		case 1:
			cout << "\nEnter the value to be Inserted : ";
			cin >> x;
			Insert(root, x);
			break;
		case 2:
			cout << "\nEnter the value to be Deleted : ";
			cin >> x;
			Remove(root, root, x);
			break;
		case 3:
			BFT(root);
			break;
		case 4:
			Pre(root);
			break;
		case 5:
			In(root);
			break;
		case 6:
			Post(root);
			break;
		}
	} while (ch != 0);
}

Binary Heap

// A C++ program to demonstrate common Binary Heap Operations
#include 
#include 
using namespace std;

// Prototype of a utility function to swap two integers
void swap(int *x, int *y);

// A class for Min Heap
class MinHeap
{
    int *harr;     // pointer to array of elements in heap
    int capacity;  // maximum possible size of min heap
    int heap_size; // Current number of elements in min heap
public:
    // Constructor
    MinHeap(int capacity);

    // to heapify a subtree with the root at given index
    void MinHeapify(int);

    int parent(int i) { return (i - 1) / 2; }

    // to get index of left child of node at index i
    int left(int i) { return (2 * i + 1); }

    // to get index of right child of node at index i
    int right(int i) { return (2 * i + 2); }

    // to extract the root which is the minimum element
    int extractMin();

    // Decreases key value of key at index i to new_val
    void decreaseKey(int i, int new_val);

    // Returns the minimum key (key at root) from min heap
    int getMin() { return harr[0]; }

    // Deletes a key stored at index i
    void deleteKey(int i);

    // Inserts a new key 'k'
    void insertKey(int k);
};

// Constructor: Builds a heap from a given array a[] of given size
MinHeap::MinHeap(int cap)
{
    heap_size = 0;
    capacity = cap;
    harr = new int[cap];
}

// Inserts a new key 'k'
void MinHeap::insertKey(int k)
{
    if (heap_size == capacity)
    {
        cout << "\nOverflow: Could not insertKey\n";
        return;
    }

    // First insert the new key at the end
    heap_size++;
    int i = heap_size - 1;
    harr[i] = k;

    // Fix the min heap property if it is violated
    while (i != 0 && harr[parent(i)] > harr[i])
    {
        swap(&harr[i], &harr[parent(i)]);
        i = parent(i);
    }
}

// Decreases value of key at index 'i' to new_val.  It is assumed that
// new_val is smaller than harr[i].
void MinHeap::decreaseKey(int i, int new_val)
{
    harr[i] = new_val;
    while (i != 0 && harr[parent(i)] > harr[i])
    {
        swap(&harr[i], &harr[parent(i)]);
        i = parent(i);
    }
}

// Method to remove minimum element (or root) from min heap
int MinHeap::extractMin()
{
    if (heap_size <= 0)
        return INT_MAX;
    if (heap_size == 1)
    {
        heap_size--;
        return harr[0];
    }

    // Store the minimum value, and remove it from heap
    int root = harr[0];
    harr[0] = harr[heap_size - 1];
    heap_size--;
    MinHeapify(0);

    return root;
}

// This function deletes key at index i. It first reduced value to minus
// infinite, then calls extractMin()
void MinHeap::deleteKey(int i)
{
    decreaseKey(i, INT_MIN);
    extractMin();
}

// A recursive method to heapify a subtree with the root at given index
// This method assumes that the subtrees are already heapified
void MinHeap::MinHeapify(int i)
{
    int l = left(i);
    int r = right(i);
    int smallest = i;
    if (l < heap_size && harr[l] < harr[i])
        smallest = l;
    if (r < heap_size && harr[r] < harr[smallest])
        smallest = r;
    if (smallest != i)
    {
        swap(&harr[i], &harr[smallest]);
        MinHeapify(smallest);
    }
}

// A utility function to swap two elements
void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

// Driver program to test above functions
int main()
{
    MinHeap h(11);
    h.insertKey(3);
    h.insertKey(2);
    h.deleteKey(1);
    h.insertKey(15);
    h.insertKey(5);
    h.insertKey(4);
    h.insertKey(45);
    cout << h.extractMin() << " ";
    cout << h.getMin() << " ";
    h.decreaseKey(2, 1);
    cout << h.getMin();
    return 0;
}

Double Linked List

#include 
using namespace std;

struct node
{
	int val;
	node *prev;
	node *next;
};

node *start;

void insert(int x)
{
	node *t = start;
	if (start != NULL)
	{
		while (t->next != NULL)
		{
			t = t->next;
		}
		node *n = new node;
		t->next = n;
		n->prev = t;
		n->val = x;
		n->next = NULL;
	}
	else
	{
		node *n = new node;
		n->val = x;
		n->prev = NULL;
		n->next = NULL;
		start = n;
	}
}

void remove(int x)
{
	node *t = start;
	while (t->val != x)
	{
		t = t->next;
	}
	t->prev->next = t->next;
	t->next->prev = t->prev;
	delete t;
}

void search(int x)
{
	node *t = start;
	int found = 0;
	while (t != NULL)
	{
		if (t->val == x)
		{
			cout << "\nFound";
			found = 1;
			break;
		}
		t = t->next;
	}
	if (found == 0)
	{
		cout << "\nNot Found";
	}
}

void show()
{
	node *t = start;
	while (t != NULL)
	{
		cout << t->val << "\t";
		t = t->next;
	}
}

void reverseShow()
{
	node *t = start;
	while (t->next != NULL)
	{
		t = t->next;
	}
	while (t != NULL)
	{
		cout << t->val << "\t";
		t = t->prev;
	}
}

int main()
{
	int choice, x;
	do
	{
		cout << "\n1. Insert";
		cout << "\n2. Delete";
		cout << "\n3. Search";
		cout << "\n4. Forward print";
		cout << "\n5. Reverse print";
		cout << "\n\nEnter you choice : ";
		cin >> choice;
		switch (choice)
		{
		case 1:
			cout << "\nEnter the element to be inserted : ";
			cin >> x;
			;
			insert(x);
			break;
		case 2:
			cout << "\nEnter the element to be removed : ";
			cin >> x;
			remove(x);
			break;
		case 3:
			cout << "\nEnter the element to be searched : ";
			cin >> x;
			search(x);
			break;
		case 4:
			show();
			break;
		case 5:
			reverseShow();
			break;
		}
	} while (choice != 0);

	return 0;
}

List Array

#include 
using namespace std;

struct list
{
	int data[50];
	int top = 0;
	bool isSorted = false;

	int BinarySearch(int *array, int first, int last, int x)
	{
		if (last < first)
		{
			return -1;
		}
		int mid = (first + last) / 2;
		if (array[mid] == x)
			return mid;
		else if (x < array[mid])
			return (BinarySearch(array, first, mid - 1, x));
		else if (x > array[mid])
			return (BinarySearch(array, mid + 1, last, x));
	}

	int LinarSearch(int *array, int x)
	{
		for (int i = 0; i < top; i++)
		{
			if (array[i] == x)
			{
				return i;
			}
		}

		return -1;
	}

	int Search(int x)
	{
		int pos = -1;

		if (isSorted)
		{
			pos = BinarySearch(data, 0, top - 1, x);
		}

		else
		{
			pos = LinarSearch(data, x);
		}

		if (pos != -1)
		{
			cout << "\nElement found at position : " << pos;
		}
		else
		{
			cout << "\nElement not found";
		}
		return pos;
	}

	void Sort()
	{
		int i, j, pos;
		for (i = 0; i < top; i++)
		{
			int min = data[i];
			for (j = i + 1; j < top; j++)
			{
				if (data[j] < min)
				{
					pos = j;
					min = data[pos];
				}
			}

			int temp = data[i];
			data[i] = data[pos];
			data[pos] = temp;
		}
		isSorted = true;
	}

	void insert(int x)
	{
		if (!isSorted)
		{

			if (top == 49)
			{
				cout << "\nOverflow";
			}
			else
			{
				data[top] = x;
				top++;
			}
		}

		else
		{
			int pos = 0;

			for (int i = 0; i < top - 1; i++)
			{
				if (data[i] <= x && x <= data[i + 1])
				{
					pos = i + 1;
					break;
				}
			}
			if (pos == 0)
			{
				pos = top - 1;
			}

			for (int i = top; i > pos; i--)
			{
				data[i] = data[i - 1];
			}
			top++;
			data[pos] = x;
		}
	}

	void Remove(int x)
	{
		int pos = Search(x);
		cout << "\n"
			 << data[pos] << " deleted";
		for (int i = pos; i < top; i++)
		{
			data[i] = data[i + 1];
		}
		top--;
	}

	void Show()
	{
		for (int i = 0; i < top; i++)
		{
			cout << data[i] << "\t";
		}
	}
};

int main()
{
	list L;
	int choice;
	int x;
	do
	{
		cout << "\n1.Insert";
		cout << "\n2.Delete";
		cout << "\n3.Search";
		cout << "\n4.Sort";
		cout << "\n5.Print";
		cout << "\n\nEnter Your Choice : ";
		cin >> choice;
		switch (choice)
		{
		case 1:
			cout << "\nEnter the element to be inserted : ";
			cin >> x;
			L.insert(x);
			break;
		case 2:
			cout << "\nEnter the element to be removed : ";
			cin >> x;
			L.Remove(x);
			break;
		case 3:
			cout << "\nEnter the element to be searched : ";
			cin >> x;
			L.Search(x);
			break;
		case 4:
			L.Sort();
			break;
		case 5:
			L.Show();
			break;
		

你可能感兴趣的:(c++,c++,编程语言,算法,数据结构)