7个重要内排序算法的实现以及实验比较

本代码片段对7个内排序算法作出实现与比较,复制粘贴代码即可编译运行

其中,最需要一定掌握的是快速排序,请一定要记得快速排序的代码shi'xi 

/************************
内排序算法的实验比较
使用C++语言分别实现插入排序、冒泡排序、选择排序、归并排序、快速排序、堆排序、基数排序算法,要求:
1)使用随机数生成方法,分别产生规模为100、1000、10000的三组自然数序列,作为各排序算法的输入;
2)算法的实现要求是稳定的(stable);
3)分别以三组自然数序列作为输入,执行各排序算法。要求每组序列各执行三次,记录各算法每次执行时间(毫秒),取平均值作为结果记入实验报告的表1中;
4)根据表1中的结果数据,通过折线图(横坐标表示输入规模,纵坐标表示平均执行时间)来对各算法的时间效率进行比较分析,回答如下问题:
–各组输入中那个排序算法时间开销最小?
随着输入规模的增长,哪个排序算法的增长趋势最缓慢?
*************************/

#include "stdafx.h"
#include<iostream>
#include<vector>
#include<stdio.h>
#include<stdlib.h>
#include<ctime>
#include<iomanip>
#define random(x) (rand()%x)
using namespace std;

//1.插入排序
//平均时间复杂度:O(N^2)
//最坏情况复杂度:O(N^2)
//最好情况复杂度:O(N)
//空间复杂度:O(1)
//最多需要n(n−1)/2次比较
//最少需要n−1次比较
//稳定排序
void insertsort(vector<int>& a)
{
	int n = a.size();
	for (int i = 1; i < n; i++)
	{
		int insert_num = a[i], j;
		for (j = i - 1; j >= 0; j--)
		{
			if (a[j] > insert_num)
				a[j + 1] = a[j];
			else
				break;
		}
		a[j + 1] = insert_num;
	}
}

//2.冒泡排序
//平均时间复杂度:O(N^2)
//最坏情况复杂度:O(N^2)
//空间复杂度:O(1)
//稳定排序
void bubblesort(vector<int>& a)
{
	int n = a.size();
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n - 1 - i; j++)
		{
			if (a[j] > a[j + 1])
				swap(a[j], a[j + 1]);
		}
	}
}


//3.选择排序
//平均时间复杂度 O(n^2)
//最坏时间复杂度 O(n^2)
//最好时间复杂度 O(n^2)
//空间复杂度 O(1)
//我这个写法 是稳定排序
void select_sort(vector<int>& vt)
{
	for (int i = 0; i < vt.size() - 1; i++)
	{
		int swap_pos = i;
		for (int j = i + 1; j < vt.size(); j++)
		{
			if (vt[swap_pos] > vt[j])
			{
				swap_pos = j;
			}
		}

		if (swap_pos != i)
		{
			swap(vt[swap_pos], vt[i]);
		}
	}
}

//4.归并排序
//平均时间复杂度:O(NlogN)
//稳定排序
vector<int> mergeHelper(vector<int> &a, int left, int right)
{
	if (left == right) return vector<int>(1, a[left]);
	int mid = (right - left) / 2 + left;
	vector<int> l = mergeHelper(a, left, mid);
	vector<int> r = mergeHelper(a, mid + 1, right);
	//merge
	vector<int> ret;
	int ll = 0, rr = 0;
	while (ll < l.size() && rr < r.size())
	{
		if (l[ll] <= r[rr])     ret.push_back(l[ll++]);
		else                    ret.push_back(r[rr++]);
	}
	while (ll < l.size()) ret.push_back(l[ll++]);
	while (rr < r.size()) ret.push_back(r[rr++]);
	return ret;
}

void mergesort(vector<int>& a)
{
	a = mergeHelper(a, 0, a.size() - 1);
}

//5.快速排序
//平均时间复杂度:O(NlogN)
//最坏情况复杂度:O(N^2)
//不稳定排序
//快排的最差时间复杂度为O(n²)
//通常出现在选择的轴值(pivot)不能将数组划分为两个长度相等的子数组的时候
//一个较好的办法是“三数取中”,查看当前数组的第一个、中间一个和最后一个位置的数组,取其中位数,以此来降低轴值选择得不好的可能性。
int findmiddle(int a, int b, int c)
{
	if (a >= b && a <= c)
		return a;
	else if (b >= a && b <= c)
		return b;
	else
		return c;
}
void quicksortHelper(vector<int>& a, int start, int end)
{
	if (start >= end) return;
	int l = start, r = end;
	int pivot = findmiddle(a[start], a[end], a[(end - start) / 2 + start]);
	while (l <= r)
	{
		while (l <= r && a[r] > pivot)  r--;
		while (l <= r && a[l] < pivot)  l++;
		if (l <= r) swap(a[l++], a[r--]);
	}
	quicksortHelper(a, start, r);
	quicksortHelper(a, l, end);
}
void quicksort(vector<int>& a)
{
	quicksortHelper(a, 0, a.size() - 1);
}

//6.堆排序
//建堆的平均时间是:O(N)
//建堆的最坏情况是:O(NlogN)
//删除元素的时间是:O(logN)
//整个排序平均时间复杂度:O(N+NlogN)=O(NlogN)
//最坏情况复杂度:O(NlogN)
//不稳定排序
//建立一个大顶堆O(n),要求就是 把最大的元素 移动到堆顶 也就是a[0]
void make_heap(vector<int>& a, int size) //size的当前堆的大小,也就是数组的前size个数
{
	for (int i = size - 1; i > 0; i--)
	{
		if (i % 2 && a[i] > a[(i - 1) / 2])//奇数
			swap(a[i], a[(i - 1) / 2]);
		else if (i % 2 == 0 && a[i] > a[(i - 2) / 2])//偶数
			swap(a[i], a[(i - 2) / 2]);
	}
}
void heapsort(vector<int>& a)
{
	int n = a.size();
	while (n)
	{
		make_heap(a, n); //每次把新的最大元素移到堆顶,也就是a[0]
		n--;
		swap(a[0], a[n]); //然后把当前最大移动到后面来作为排好序的元素
	}
}

//7.基数排序
//时间复杂度最坏情况、平均情况、最差情况均为O(d(n+r))
//其中,r代表关键码的基数,d代表长度,n代表关键码的个数
int maxbit(vector<int>& data)
{	
	int n = data.size();
	int d = 1; //保存最大的位数
	int p = 10;
	for (int i = 0; i < n; ++i)
	{
		while (data[i] >= p)
		{
			p *= 10;
			++d;
		}
	}
	return d;
}

void radixsort(vector <int>& data) //基数排序
{
	int n = data.size();
	int d = maxbit(data);
	int tmp[10000] = {};
	int count[10]; //计数器
	int i, j, k;
	int radix = 1;
	for (i = 1; i <= d; i++) //进行d次排序
	{
		for (j = 0; j < 10; j++)
			count[j] = 0; //每次分配前清空计数器
		for (j = 0; j < n; j++)
		{
			k = (data[j] / radix) % 10; //统计每个桶中的记录数
			count[k]++;
		}
		for (j = 1; j < 10; j++)
			count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶
		for (j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
		{
			k = (data[j] / radix) % 10;
			tmp[count[k] - 1] = data[j];
			count[k]--;
		}
		for (j = 0; j < n; j++) //将临时数组的内容复制到data中
			data[j] = tmp[j];
		radix = radix * 10;
	}
}


int main()
{
	vector<int> A;
	srand((int)(time(0)));
	for (int i = 0;i < 100;i++)
		A.push_back(random(50000));
	cout << "100个数据为:" << endl;
	
	vector<int> A2;
	vector<int> A3;
	vector<int> A4;
	vector<int> A5;
	vector<int> A6;
	vector<int> A7;
	for (int i = 0;i < 100;i++)
	{
		A2.push_back(A[i]);
		A3.push_back(A[i]);
		A4.push_back(A[i]);
		A5.push_back(A[i]);
		A6.push_back(A[i]);
		A7.push_back(A[i]);
	}

	clock_t start = clock();
	insertsort(A);
	clock_t end = clock();
	cout << "1.插入排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC *1000<< "ms\n";
	
	start = clock();
	bubblesort(A2);
	end = clock();
	cout << "2.冒泡排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC*1000 << "ms\n";

	start = clock();
	select_sort(A3);
	end = clock();
	cout << "3.选择排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC*1000 << "ms\n";
	
	start = clock();
	mergesort(A4);
	end = clock();
	cout << "4.归并排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC *1000<< "ms\n";

	start = clock();
	quicksort(A5);
	end = clock();
	cout << "5.快速排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	heapsort(A6);
	end = clock();
	cout << "6.堆的排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC*1000 << "ms\n";

	start = clock();
	radixsort(A7);
	end = clock();
	cout << "7.基数排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC *1000<< "ms\n";
	
	cout << endl << endl;

	cout << "1000个数据为:" << endl;
	vector<int> AA;
	srand((int)(time(0)));
	for (int i = 0;i < 1000;i++)
		AA.push_back(random(50000));
	
	cout << endl;
	vector<int> AA2;
	vector<int> AA3;
	vector<int> AA4;
	vector<int> AA5;
	vector<int> AA6;
	vector<int> AA7;
	for (int i = 0;i < 1000;i++)
	{
		AA2.push_back(AA[i]);
		AA3.push_back(AA[i]);
		AA4.push_back(AA[i]);
		AA5.push_back(AA[i]);
		AA6.push_back(AA[i]);
		AA7.push_back(AA[i]);
	}

    start = clock();
 	insertsort(AA);
	end = clock();
	cout << "1.插入排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	bubblesort(AA2);
	end = clock();
	cout << "2.冒泡排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	select_sort(AA3);
	end = clock();
	cout << "3.选择排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	mergesort(AA4);
	end = clock();
	cout << "4.归并排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	quicksort(AA5);
	end = clock();
	cout << "5.快速排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	heapsort(AA6);
	end = clock();
	cout << "6.堆的排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	radixsort(AA7);
	end = clock();
	cout << "7.基数排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	cout << endl << endl;

	
	vector<int> AAA;
	srand((int)(time(0)));
	for (int i = 0;i < 10000;i++)
		AAA.push_back(random(50000));
	
	vector<int> AAA2;
	vector<int> AAA3;
	vector<int> AAA4;
	vector<int> AAA5;
	vector<int> AAA6;
	vector<int> AAA7;
	for (int i = 0;i < 10000;i++)
	{
		AAA2.push_back(AAA[i]);
		AAA3.push_back(AAA[i]);
		AAA4.push_back(AAA[i]);
		AAA5.push_back(AAA[i]);
		AAA6.push_back(AAA[i]);
		AAA7.push_back(AAA[i]);
	}
	cout << "10000个数据为:" << endl;
	start = clock();
	insertsort(AAA);
	end = clock();
	cout << "1.插入排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	bubblesort(AAA2);
	end = clock();
	cout << "2.冒泡排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	select_sort(AAA3);
	end = clock();
	cout << "3.选择排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	mergesort(AAA4);
	end = clock();
	cout << "4.归并排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	quicksort(AAA5);
	end = clock();
	cout << "5.快速排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	heapsort(AAA6);
	end = clock();
	cout << "6.堆的排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";

	start = clock();
	radixsort(AAA7);
	end = clock();
	cout << "7.基数排序时间为:" << (double)(end - start) / CLOCKS_PER_SEC * 1000 << "ms\n";
	cout << "10000个数据为:" << endl;
	
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

原创文章 18 获赞 57 访问量 10万+

猜你喜欢

转载自blog.csdn.net/Linrena/article/details/84262113