9种排序算法对比

目录

本文里所有代码均为本人原创,若有错误请指正!!!

目录

  • 前言
  • 一、插入排序
    • 1.直接插入
    • 2.折半插入
    • 3.希尔排序
  • 二、选择排序
    • 1.直接选择
    • 2.树形选择
  • 三、交换排序
    • 1.冒泡排序
    • 2.快速排序
  • 四、其他排序
    • 1.归并排序
    • 2.基数排序
  • 总结


前言

        本人目前为大二学生,算法基础相对薄弱,写此blog来加强自己的算法能力,为ACM等竞赛打好基础。此blog可能有许多错误,还望各位大佬指正!若有志同道合的朋友,可以一起学习算法,共同进步!


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

一、插入排序

        插入排序,顾名思义,就是在待排序的数组中间插入元素,最终实现排序数组的效果。

1.直接插入

        直接插入是最基础的排序方法,其原理为:我们认为前面k个数组是已经排序好的状态,数组中的第k+1个元素,和前面k个元素进行比较,找到他要插入的位置,将后面的元素依次往后移即可。时间复杂度为O(n^2)。(为了方便对比数组大小均为100000(10^5),并且于直接插入算法进行比较)。

具体代码为:

#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;
}

        排序数组大小为100000是数组(10^5)共用时5727ms。经验证结果正确。

 2.折半插入

       折半插入就是在直接插入算法的基础上的一个升级,其实我们并不需要去遍历前面的k个元素进行比较,我们只需要和前面数组大小为k的数组的中间值进行比较即可。如果这个数比中间值大,那么就把区间放到都半部分去继续进行比较;否则就在半部分进行比较。最后一定会找到插入的位置,这个查找的时间复杂度就降低到了O(logn)。找到位置后,在继续插入即可。这样这个算法的时间复杂度就是O(nlogn)。

       具体代码为:

#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;
}

        该算法排序数组大小为100000的数组需要2845ms。经验证结果正确。 

           时间上有问题,代码不知道哪里有问题,还望大佬指出!!!

3.希尔排序

        希尔排序的原理为:将数组中间隔gap的元素分为一组,并将组内进行排序,然后逐步减小gap,当gap为1时,数组就已经排序好了。这里我们选择的是让gap/=2,来逐步减小gap,这样这个算法的时间复杂度就是O(nlogn^2)或者是O(n^1.3)了。

具体代码:

#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;
}

         该算法排序数组大小为100000的数组仅需要28ms。经验证结果正确。 

二、选择排序

        选择排序,就是每次都选出这个数组中最大或者最小的元素,这样就可以将数组排序好了。

1.直接选择

        直接排序是最直接的排序方式,循环n次,每次都选出数组中第k小的数据,并把它放在数组的第k个位置。时间复杂度为O(n^2)。

具体代码为:

#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;
}

        该算法排序数组大小为100000的数组需要4945ms。经验证结果正确。

2.树形选择

        树形选择排序就是利用空间换取时间的思想。将一个数组弄成补成一个2的k次方的数组,多出来的部分用无穷大进行表示。这样我们就可以形成一个完全二叉树,并且每次对比都把2个中最小的一个数,赋值给该节点,这样头节点的数据就是这个数组中最小的数据。然后将这个数据赋值给原数组,并将该数设置为无穷大,进行下一轮迭代。这个算法的时间复杂度为O(nlogn)。

具体代码为:

#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;
}

 

        该算法排序数组大小为100000的数组仅需要29ms,不过需要大量的空间来实现。经验证后结果正确。

三、交换排序

        交换排序就是不断的将大的数与小的数交换,将数组进行排序的算法。

1.冒泡排序

        冒泡排序就是不断地将大的数和小的数进行交换,大的数放在后面,把最大的数放在数组的末尾。当某一次遍历时若没有发生交换,说明该数组已经排序好了,这时候我们就可以break,跳出循环了。该算法的时间复杂度为O(n^2)。

具体代码为:

#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;
}

         该算法排序数组大小为100000的数组需要25806ms,时间开销较大。经验证后结果正确。

2.快速排序

         快速排序是在数组里面选取一个中间的数作为比较值,将比该值大的元素放在右边,比该元素小的元素放在左边。这样再对这个左右2个数组进行相同的操作,当两个边的边界值相差1时数组就已经排序好了。

        这里我们选取3个数进行比较选其中中间值,让中间值尽可能地接近该数组的中位数,来减少递归后的数组的时间复杂度,并且当数组足够小时,可以不需要递归调用,可以选择直接插入的算法进行排序,这样也可以减少时间复杂度。最终时间复杂度为O(nlogn)。

具体代码为:

#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;
}

         该算法排序数组大小为100000的数组仅需要14ms。经验证后结果正确。

 

四、其他排序

1.归并排序

        归并排序就是将数组逐步拆分为大小较小的数组,然后逐渐把数组进行合并这样就可以将时间复杂度降低到O(nlogn)了。

        注意:这里我们需要把原数组的大小拓展为2的k次方。

        具体代码为:

#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;
}

        该算法排序数组大小为100000的数组仅需要15ms。经验证后结果正确。

2.基数排序

        基数排序,就是以某一个进制为基础,将该数组分为若干个数组(几进制就用几个数组),将余数相同的数放在一个数组里,然后将这个数右移一位。这里需要找到,最大的一个数的最高位次,就可以知道需要迭代多少轮了。这样排序后都是按照位次一步一步排序好的,所以最后结果也是对的,不过这个需要大量的空间去存放数据。时间复杂度为O(nlogn)。

具体代码为:

#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;
}

        该算法排序数组大小为100000的数组仅需要13ms。经验证结果正确。

 


总结

        这个9种排序算法的时间快慢为:基数排序>快速排序>归并排序>希尔排序>树形排序>折半插入>直接选择>直接插入>冒泡排序。

         其中,空间开销较大的有:基数排序和树形排序。

        每个排序算法都有自己的用途,不能单独从时间快慢上判断这个排序算法的好坏!

        以上代码为本人自己原创,可能有许多错误和理解不到位的地方,还望各位大佬指正!!!

猜你喜欢

转载自blog.csdn.net/m0_74133913/article/details/129760431