Comparison of 9 sorting algorithms

Table of contents

All the codes in this article are original, please correct me if there are any mistakes! ! !

Table of contents

  • foreword
  • 1. Insertion sort
    • 1. Direct insertion
    • 2. Insert in half
    • 3. Hill sort
  • 2. Selection sort
    • 1. Direct selection
    • 2. Tree selection
  • 3. Exchange sort
    • 1. Bubble sort
    • 2. Quick Sort
  • 4. Other sorting
    • 1. Merge sort
    • 2. Radix sort
  • Summarize


foreword

        I am currently a sophomore and my algorithm foundation is relatively weak. I write this blog to strengthen my algorithm ability and lay a solid foundation for competitions such as ACM. There may be many mistakes in this blog, and I hope you can correct me! If you have like-minded friends, you can learn algorithms together and make progress together!


提示:以下代码仅供参考!!!

1. Insertion sort

        Insertion sort, as the name suggests, is to insert elements in the middle of the array to be sorted, and finally achieve the effect of sorting the array.

1. Direct insertion

        Direct insertion is the most basic sorting method. Its principle is: we think that the first k arrays are in a sorted state, compare the k+1th element in the array with the previous k elements, find the position to be inserted, and move the subsequent elements backward one by one. The time complexity is O(n^2). (For the convenience of comparison, the size of the array is 100000 (10^5), and it is compared with the direct insertion algorithm).

The specific code is:

#include <iostream>
#include <stdio.h>
#include <time.h>
#include <algorithm>

using namespace std;


void Print(int* a, int n);
void direct_sort(int* a, int n);

void direct_sort(int* a, int n)
{
	if (n <= 1)
	{
		cout << "Array Error!" << endl;
	}
	for (int i = 1; i < n; i++)
	{
		int k = 0;
		while (a[i] > a[k])k++;
		int temp = a[i];
		for (int j = i; j > k; j--)
		{
			a[j] = a[j - 1];
		}
		a[k] = temp;
	}
}

void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
}

int main()
{
	srand((unsigned)time(NULL));
	int n;
	cout << "请输入待排序的数组大小:";
	cin >> n;
	int* num = new int[n];
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num[i] = rand();
		num1[i] = num[i];
	}
	clock_t start = clock();
	direct_sort(num, n);
	clock_t end = clock();
	cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	sort(num1, num1 + n);
	bool equal = true;
	for (int i = 0; i < n; i++)
	{
		if (num[i] != num1[i])
		{
			equal = false;
			break;
		}
	}
	if (equal)cout << "Right!" << endl;
	else cout << "Error!" << endl;
	delete[]num;
	delete[]num1;
	return 0;
}

        The size of the sorted array is 100000, which is 5727ms when the array (10^5) is shared. The verified result is correct.

 2. Insert in half

       Half insertion is an upgrade based on the direct insertion algorithm. In fact, we don't need to traverse the previous k elements for comparison. We only need to compare with the median value of the previous array whose size is k. If this number is greater than the median value, then put the interval in half to continue the comparison; otherwise, compare in half. In the end, the insertion position must be found, and the time complexity of this search is reduced to O(logn). After finding the position, continue to insert it. So the time complexity of this algorithm is O(nlogn).

       The specific code is:

#include <iostream>
#include <stdio.h>
#include <omp.h>
#include <stdlib.h>
#include <algorithm>

using namespace std;

void Binary_Sort(int* a, int n);
void Print(int* a, int n);
int find_insert_point(int* a, int n, int l, int r, int i);
void direct_sort(int* a, int n);

void direct_sort(int* a, int n)
{
	if (n <= 1)
	{
		cout << "Array Error!" << endl;
	}
	for (int i = 1; i < n; i++)
	{
		int k = 0;
		while (a[i] > a[k])k++;
		int temp = a[i];
		for (int j = i; j > k; j--)
		{
			a[j] = a[j - 1];
		}
		a[k] = temp;
	}
}

int find_insert_point(int* a, int n, int l, int r, int i)
{
	if (l > r)return l;
	int m = (l + r) / 2;
	if (a[i] < a[m])return find_insert_point(a, n, l, m - 1, i);
	else return find_insert_point(a, n, m + 1, r, i);
}

void Binary_Sort(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		int p = find_insert_point(a, n, 0, i - 1, i);
		int temp = a[i];
		for (int j = i; j > p; j--)
		{
			a[j] = a[j - 1];
		}
		a[p] = temp;
	}
}

void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
}

int main()
{
	srand((unsigned)time(NULL));
	cout << "请输入待排序的数组大小:";
	int n;
	cin >> n;
	int* num = new int[n];
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num[i] = rand();
		num1[i] = num[i];
	}
	clock_t start = clock();
	Binary_Sort(num, n);
	clock_t end = clock();
	cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	//Print(num, n);
	clock_t start1 = clock();
	direct_sort(num1, n);
	clock_t end1 = clock();
	cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	bool equal = true;
	for (int i = 0; i < n; i++)
	{
		if (num[i] != num1[i])
		{
			equal = false;
			break;
		}
	}
	if (equal)cout << "Right!" << endl;
	else cout << "Error!" << endl;
	delete[]num;
	delete[]num1;
	return 0;
}

        This algorithm takes 2845ms to sort an array with an array size of 100000. The verified result is correct. 

           There is a problem with the time, and the code does not know where there is a problem, and I hope the boss can point it out! ! !

3. Hill sort

        The principle of Hill sorting is: divide the gap elements in the array into a group, and sort the group, and then gradually reduce the gap. When the gap is 1, the array is already sorted. Here we choose to let gap/=2 to gradually reduce the gap, so that the time complexity of this algorithm is O(nlogn^2) or O(n^1.3).

Specific code:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>

using namespace std;

void Shell_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);

void direct_sort(int* a, int n)
{
	if (n <= 1)
	{
		cout << "Array Error!" << endl;
	}
	for (int i = 1; i < n; i++)
	{
		int k = 0;
		while (a[i] > a[k])k++;
		int temp = a[i];
		for (int j = i; j > k; j--)
		{
			a[j] = a[j - 1];
		}
		a[k] = temp;
	}
}

void Swap(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

void Shell_Sort(int* a, int n)
{
	//Print(a, n,n);
	for (int gap = n/2; gap >= 1; gap >>= 1)
	{
		for (int i = gap; i < n; i++)
		{
			int temp = a[i];
			for (int j = i - gap; j >= 0; j -= gap)
			{
				if (temp < a[j])Swap(a[j + gap], a[j]);
				else break;
			}
		}
	}
}

void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ",a[i]);
		//if ((i+1) % gap == 0)cout << endl;
	}
	cout << endl;
}
 
int main()
{
	srand((unsigned)time(NULL));
	int n;
	cout << "请输入待排序的数组的大小:";
	cin >> n;
	int* num = new int[n];
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num[i] = rand();
		num1[i] = num[i];
	}
	clock_t start = clock();
	Shell_Sort(num, n);
	clock_t end = clock();
	cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	//Print(num, n);
	clock_t start1 = clock();
	direct_sort(num1, n);
	clock_t end1 = clock();
	cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	bool equal = true;
	for (int i = 0; i < n; i++)
	{
		if (num[i] != num1[i])
		{
			equal = false;
			break;
		}
	}
	if (equal)cout << "Right!" << endl;
	else cout << "Error!" << endl;
	delete[]num;
	delete[]num1;
	return 0;
}

         The algorithm takes only 28ms to sort an array of size 100000. The verified result is correct. 

 

2. Selection sort

        Selection sorting is to select the largest or smallest element in the array every time, so that the array can be sorted.

1. Direct selection

        Direct sorting is the most direct sorting method. It loops n times, and each time selects the kth smallest data in the array and puts it in the kth position of the array. The time complexity is O(n^2).

The specific code is:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>

using namespace std;

void Choose_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);

void direct_sort(int* a, int n)
{
	if (n <= 1)
	{
		cout << "Array Error!" << endl;
	}
	for (int i = 1; i < n; i++)
	{
		int k = 0;
		while (a[i] > a[k])k++;
		int temp = a[i];
		for (int j = i; j > k; j--)
		{
			a[j] = a[j - 1];
		}
		a[k] = temp;
	}
}

void Swap(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
		//if ((i+1) % gap == 0)cout << endl;
	}
	cout << endl;
}

void Choose_Sort(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		int m = a[i];
		int dex = i;
		for (int j = i + 1; j < n; j++)
		{
			if (a[j] < m)
			{
				m = a[j];
				dex = j;
			}
		}
		Swap(a[i], a[dex]);
	}
}

int main()
{
	srand((unsigned)time(NULL));
	cout << "请输入待排序的数组的大小:";
	int n;
	cin >> n;
	int* num = new int[n];
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num[i] = rand();
		num1[i] = num[i];
	}
	clock_t start = clock();
	Choose_Sort(num, n);
	clock_t end = clock();
	cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	//Print(num, n);
	clock_t start1 = clock();
	direct_sort(num1, n);
	clock_t end1 = clock();
	cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	bool equal = true;
	for (int i = 0; i < n; i++)
	{
		if (num[i] != num1[i])
		{
			equal = false;
			break;
		}
	}
	if (equal)cout << "Right!" << endl;
	else cout << "Error!" << endl;
	delete[]num;
	delete[]num1;
	return 0;
}

        This algorithm takes 4945ms to sort an array with an array size of 100000. The verified result is correct.

2. Tree selection

        Tree selection sorting is the idea of ​​using space in exchange for time. Complement an array into an array of 2 to the kth power, and the extra part is represented by infinity. In this way, we can form a complete binary tree, and assign the smallest number among the two to the node for each comparison, so that the data of the head node is the smallest data in this array. Then assign this data to the original array, and set the number to infinity for the next iteration. The time complexity of this algorithm is O(nlogn).

The specific code is:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
#define M 0x7fffffff

using namespace std;

void Tree_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);


void Swap(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	cout << endl;
}

void direct_sort(int* a, int n)
{
	if (n <= 1)
	{
		cout << "Array Error!" << endl;
	}
	for (int i = 1; i < n; i++)
	{
		int k = 0;
		while (a[i] > a[k])k++;
		int temp = a[i];
		for (int j = i; j > k; j--)
		{
			a[j] = a[j - 1];
		}
		a[k] = temp;
	}
}

void Tree_Sort(int* a, int n)
{
	int n1 = n,t = 0;
	while (n1)
	{
		n1 >>= 1;
		t++;
	}
	int n2 = 1;
	n2 <<= t;
	int n_max = 2 * n2 - 1;
	int* num = new int[n_max];
	for (int i = 0; i < n2; i++)
	{
		if (i < n)num[i] = a[i];
		else num[i] = M;
	}
	for (int i = n2; i < n_max; i++)
	{
		num[i] = min(num[(i - n2) * 2], num[(i - n2) * 2 + 1]);
	}
	int h = n2;
	int pre1 = 0;
	for (int i = 0; i < 2 * n2 - 1; i++)
	{
		cout << num[i] << " ";
		if (i+1 == pre1 + h)
		{
			pre1 += h;
			cout << endl;
			h >>= 1;		
		}
	}
	cout << endl;
	a[0] = num[n_max-1];
	for (int i = 0; i < n - 1; i++)
	{
		int temp = num[n_max - 1];
		int t = n_max - 1;
		while (t >= n2)
		{
			if (num[(t - n2) * 2] == temp)t = (t - n2) * 2;
			else t = (t - n2) * 2 + 1;
		}
		num[t] = M;
		while (t < n_max - 1)
		{
			num[n2 + t / 2] = min(num[t], num[t ^ 1]);
			t = n2 + t / 2;
		}
		a[i + 1] = num[n_max - 1];
	}
	delete[]num;
}

int main()
{
	srand((unsigned)time(NULL));
	cout << "请输入待排序的数组大小:";
	int n;
	cin >> n;
	int* num = new int[n];
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num[i] = rand();
		num1[i] = num[i];
	}
	clock_t start = clock();
	Tree_Sort(num, n);
	clock_t end = clock();
	cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	//Print(num, n);
	clock_t start1 = clock();
	direct_sort(num1, n);
	clock_t end1 = clock();
	cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	bool equal = true;
	for (int i = 0; i < n; i++)
	{
		if (num[i] != num1[i])
		{
			equal = false;
			break;
		}
	}
	if (equal)cout << "Right!" << endl;
	else cout << "Error!" << endl;
	delete[]num;
	delete[]num1;
	return 0;
}

 

        The algorithm takes only 29ms to sort an array with an array size of 100,000, but requires a lot of space to implement. After verification, the result is correct.

3. Exchange sort

        Exchange sorting is an algorithm that continuously exchanges large numbers with small numbers and sorts the array.

1. Bubble sort

        Bubble sorting is to continuously exchange large numbers with small numbers, put the large numbers behind, and put the largest numbers at the end of the array. If there is no exchange during a certain traversal, it means that the array has been sorted. At this time, we can break and jump out of the loop. The time complexity of this algorithm is O(n^2).

The specific code is:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>

using namespace std;

void Bubble_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);

void Swap(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	cout << endl;
}

void direct_sort(int* a, int n)
{
	if (n <= 1)
	{
		cout << "Array Error!" << endl;
	}
	for (int i = 1; i < n; i++)
	{
		int k = 0;
		while (a[i] > a[k])k++;
		int temp = a[i];
		for (int j = i; j > k; j--)
		{
			a[j] = a[j - 1];
		}
		a[k] = temp;
	}
}

void Bubble_Sort(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		bool over = true;
		for (int j = 0; j < n - i - 1; j++)
		{
			if (a[j] > a[j + 1])
			{
				Swap(a[j], a[j + 1]);
				over = false;
			}
		}
		if (over)break;
	}
}

int main()
{
	srand((unsigned)time(NULL));
	int n;
	cout << "请输入待排序的数组的大小:";
	cin >> n;
	int* num = new int[n];
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num[i] = rand();
		num1[i] = num[i];
	}
	clock_t start = clock();
	Bubble_Sort(num, n);
	clock_t end = clock();
	cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	//Print(num, n);
	clock_t start1 = clock();
	direct_sort(num1, n);
	clock_t end1 = clock();
	cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	bool equal = true;
	for (int i = 0; i < n; i++)
	{
		if (num[i] != num1[i])
		{
			equal = false;
			break;
		}
	}
	if (equal)cout << "Right!" << endl;
	else cout << "Error!" << endl;
	delete[]num;
	delete[]num1;
	return 0;
}

         This algorithm takes 25806ms to sort an array with an array size of 100,000, and the time overhead is relatively large. After verification, the result is correct.

2. Quick Sort

         Quick sort is to select an intermediate number in the array as a comparison value, and place elements larger than this value on the right, and elements smaller than this element on the left. In this way, the same operation is performed on the left and right arrays. When the boundary values ​​​​of the two sides differ by 1, the arrays are already sorted.

        Here we select 3 numbers for comparison and select the middle value, so that the middle value is as close as possible to the median of the array, so as to reduce the time complexity of the recursive array, and when the array is small enough, there is no need for recursive calls, and you can choose a direct insertion algorithm for sorting, which can also reduce time complexity. The final time complexity is O(nlogn).

The specific code is:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>

using namespace std;

void Quick_Sort(int* a, int n);
void Quick_Divide(int* a, int left, int right);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int left,int right);

void Swap(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	cout << endl;
}

void direct_sort(int* a, int left,int right)
{
	if (left > right)
	{
		cout << "Array Error!" << endl;
	}
	for (int i = left + 1; i <= right; i++)
	{
		int k = left;
		while (a[i] > a[k])k++;
		int temp = a[i];
		for (int j = i; j > k; j--)
		{
			a[j] = a[j - 1];
		}
		a[k] = temp;
	}
}

void Quick_Divide(int* a, int left, int right)
{
	if (right <= left)return;
	if (right - left < 10)
	{
		direct_sort(a, left, right);
		return;
	}
	int num[3] = { a[left],a[right],a[(left + right) / 2] };
	sort(num, num+3);
	int dex;
	if (num[1] == a[left])dex = left;
	else if (num[1] == a[right])dex = right;
	else dex = (left + right) / 2;
	Swap(a[dex], a[left]);
	int i = left, j = right;
	int temp = a[left];
	while (i < j)
	{
		while (i < j && a[i] < temp)i++;
		while (i < j && a[j] >= temp)j--;
		Swap(a[i], a[j]);
	}
	if (a[i] > temp)
	{
		Quick_Divide(a, left, i - 1);
		Quick_Divide(a, i, right);
	}
	else
	{
		Quick_Divide(a, left, i);
		Quick_Divide(a, i + 1, right);
	}
}

void Quick_Sort(int* a, int n)
{
	Quick_Divide(a, 0, n - 1);
}

int main()
{
	srand((unsigned)time(NULL));
	int n;
	cout << "请输入待排序的数组的大小:";
	cin >> n;
	int* num = new int[n];
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num[i] = rand();
		num1[i] = num[i];
	}
	clock_t start = clock();
	Quick_Sort(num, n);
	clock_t end = clock();
	cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	//Print(num, n);
	clock_t start1 = clock();
	direct_sort(num1, 0, n - 1);
	clock_t end1 = clock();
	cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	bool equal = true;
	for (int i = 0; i < n; i++)
	{
		if (num[i] != num1[i])
		{
			equal = false;
			break;
		}
	}
	if (equal)cout << "Right!" << endl;
	else cout << "Error!" << endl;
	delete[]num;
	delete[]num1;
	return 0;
}

         The algorithm takes only 14ms to sort an array of size 100000. After verification, the result is correct.

 

4. Other sorting

1. Merge sort

        Merge sort is to gradually split the array into smaller arrays, and then gradually merge the arrays so that the time complexity can be reduced to O(nlogn).

        Note: Here we need to expand the size of the original array to the kth power of 2.

        The specific code is:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>

using namespace std;

#define M 0x7fffffff

void Merge_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);
void Merge(int* a, int n, int hn);

void direct_sort(int* a, int n)
{
	if (n <= 1)
	{
		cout << "Array Error!" << endl;
	}
	for (int i = 1; i < n; i++)
	{
		int k = 0;
		while (a[i] > a[k])k++;
		int temp = a[i];
		for (int j = i; j > k; j--)
		{
			a[j] = a[j - 1];
		}
		a[k] = temp;
	}
}

void Swap(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

void Merge_Sort(int* a, int n)
{
	//Print(a, n);
	int t = 0;
	int n1 = n;
	while (n1)
	{
		n1 >>= 1;
		t++;
	}
	int n2 = 1;
	for (int i = 0; i < t; i++)
	{
		n2 <<= 1;
	}
	int* num = new int[n2];
	for (int i = 0; i < n; i++)
	{
		num[i] = a[i];
	}
	for (int i = n; i < n2; i++)
	{
		num[i] = M;
	}
	for (int i = 0; i < n2 / 2; i++)
	{
		if (num[2 * i] > num[2 * i + 1])Swap(num[2 * i], num[2 * i + 1]);
	}
	int hn = 2;
	while (hn <= n2 / 2)
	{
		Merge(num, n2, hn);
		hn <<= 1;
		//Print(num, n);
	}
	//Print(num, n2);
	for (int i = 0; i < n; i++)
	{
		a[i] = num[i];
		
	}
	//Print(a, n);
}
void Merge(int* num, int n, int hn)
{
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num1[i] = num[i];
	}
	int t = 2 * hn;
	for (int i = 0; i < n / t; i++)
	{
		int start = i * t, end = start + t - 1, k = start, p1 = start, p2 = start + hn;
		while (p1 < start + hn && p2<=end)
		{
			if (num1[p1] <= num[p2])
			{				
				num[k++] = num1[p1++];
				//if (k == 1)cout << num[0] << endl;
			}
			else
			{
				num[k++] = num1[p2++];
				//if (k == 1)cout << num[0] << endl;
			}
		}
		while (p1 < start + hn)num[k++] = num1[p1++];
		while (p2 <= end)num[k++] = num1[p2++];
	}
	delete[]num1;
}
void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ",a[i]);
		//if ((i+1) % gap == 0)cout << endl;
	}
	cout << endl;
}

int main()
{
	srand((unsigned)time(NULL));
	cout << "请输入待排序的数组的大小:";
	int n;
	cin >> n;
	int* num = new int[n];
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num[i] = rand();
		num1[i] = num[i];
	}
	clock_t start = clock();
	Merge_Sort(num, n);
	clock_t end = clock();
	cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	//Print(num, n);
	clock_t start1 = clock();
	direct_sort(num1, n);
	clock_t end1 = clock();
	cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	bool equal = true;
	for (int i = 0; i < n; i++)
	{
		if (num[i] != num1[i])
		{
			equal = false;
			break;
		}
	}
	if (equal)cout << "Right!" << endl;
	else cout << "Error!" << endl;
	delete[]num;
	delete[]num1;
	return 0;
}

        The algorithm takes only 15ms to sort an array of size 100000. After verification, the result is correct.

2. Radix sort

        Radix sorting is to divide the array into several arrays based on a certain base system (several bases are used), put the numbers with the same remainder in one array, and then shift the number to the right by one. Here we need to find the highest order of the largest number, and then we can know how many iterations need to be iterated. After sorting in this way, they are sorted step by step according to the order, so the final result is also correct, but this requires a lot of space to store data. The time complexity is O(nlogn).

The specific code is:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>

using namespace std;

void Base_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);
void Base_Sort_pre(int* a, int n, int loop);

void direct_sort(int* a, int n)
{
	if (n <= 1)
	{
		cout << "Array Error!" << endl;
	}
	for (int i = 1; i < n; i++)
	{
		int k = 0;
		while (a[i] > a[k])k++;
		int temp = a[i];
		for (int j = i; j > k; j--)
		{
			a[j] = a[j - 1];
		}
		a[k] = temp;
	}
}

void Swap(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
		//if ((i+1) % gap == 0)cout << endl;
	}
	cout << endl;
}


void Base_Sort_pre(int* a, int n,int loop)
{
	//cout << t << endl;	
	int d[10] = { 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 };
	int* bucket[10] = {  };
	int c[10] = { 0 };
	for (int j = 0; j < n; j++)
	{
		c[(a[j] / d[loop]) % 10]++;
	}
	for (int k = 0; k < 10; k++)
	{
		bucket[k] = (int*)malloc(c[k] * sizeof(int));
	}
	for (int m = 0; m < 10; m++)c[m] = 0;
	for (int l = 0; l < n; l++)
	{
		int row = (a[l] / d[loop]) % 10;
		bucket[row][c[row]] = a[l];
		c[row]++;
	}
	int s = 0;
	for (int x = 0; x < 10; x++)
	{
		for (int y = 0; y < c[x]; y++)
		{
			a[s] = bucket[x][y];
			s++;
		}
	}
	for (int p = 0; p < 10; p++)
	{
		free(bucket[p]);
	}
}

void Base_Sort(int* a, int n)
{
	int ma = 0;
	for (int i = 0; i < n; i++)
	{
		if (a[i] > ma)ma = a[i];
	}
	int t = 0;
	int ai = ma;
	//cout << ai << endl;
	while (ai)
	{
		ai /= 10;
		t++;
	}
	for (int i = 0; i < t; i++)
	{
		Base_Sort_pre(a, n, i);
	}
}
int main()
{
	srand((unsigned)time(NULL));
	cout << "请输入待排序的数组的大小:";
	int n;
	cin >> n;
	int* num = new int[n];
	int* num1 = new int[n];
	for (int i = 0; i < n; i++)
	{
		num[i] = rand();
		num1[i] = num[i];
	}
	clock_t start = clock();
	Base_Sort(num, n);
	clock_t end = clock();
	cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	//Print(num, n);
	clock_t start1 = clock();
	direct_sort(num1,n);
	clock_t end1 = clock();
	cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
	bool equal = true;
	for (int i = 0; i < n; i++)
	{
		if (num[i] != num1[i])
		{
			equal = false;
			break;
		}
	}
	//printf("%d\n", equal);
	if (equal)cout << "Right!" << endl;
	else cout << "Error!" << endl;
	delete[]num;
	delete[]num1;
	return 0;
}

        The algorithm takes only 13ms to sort an array of size 100000. The verified result is correct.

 


Summarize

        The time speed of these 9 sorting algorithms is: radix sorting > quick sorting > merge sorting > Hill sorting > tree sorting > half insertion > direct selection > direct insertion > bubble sort.

         Among them, the space-intensive ones are: radix sorting and tree sorting.

        Each sorting algorithm has its own use, and the quality of the sorting algorithm cannot be judged from the speed of time alone!

        The above code is my own original creation, there may be many mistakes and incomprehensions, and I hope you can correct me! ! !

Guess you like

Origin blog.csdn.net/m0_74133913/article/details/129760431