七大排序算法

#include
using std::cout;
using std::endl;
using std::move;
#include
using std::uniform_int_distribution;
using std::default_random_engine;
#include
#include
using std::vector;
#include
using std::swap;
#include
#pragma comment(lib,"winmm.lib")

void BubbleSort(vector arr) {

	/*
	* 冒泡排序原理:
	* 将数组最大元素逐一交换到最后的位置,再将次大元素放到倒数第二个位置......
	* 时间复杂度为 O(n*n)
	*/

	DWORD start, end;
	start = timeGetTime();//开始排序

	for (int i = 0; i < arr.size() - 1; ++i)
	{
		bool flag = true;
		for (int j = 0; j < arr.size() - i - 1; ++j)
		{
			if (arr[j] > arr[j + 1])
			{
				swap(arr[j], arr[j + 1]);
				flag = false;
			}
				
		}
		if (flag) {
			break;
		}
	}

	//排序结束
	end = timeGetTime() - start;
	cout << "冒泡排序用时(毫秒):" << end << endl;;
}

void SelectionSort(vectorarr) {

	/*
	* 选择排序原理:
	* 遍历找到最小元素,放到第一位;再找次小元素放到第二位.....
	* 可以用来找前几个最大或最小的元素
	* 时间复杂度为 O(n*n)
	*/
	DWORD start, end;
	start = timeGetTime();//开始排序

	for (int i = 0; i < arr.size(); ++i)
	{
		int index = i;
		for (int j = i+1; j < arr.size(); ++j)
		{
			if (arr[j] < arr[index]) 
			{
				index = j;
			}
		}
		swap(arr[i], arr[index]);
	}

	//for (auto i : arr)
	//{
	//	cout << i << " ";
	//}

		//排序结束
	end = timeGetTime() - start;
	cout << "选择排序用时(毫秒):" << end << endl;
}

void InsertionSort(vectorarr)
{
	/*
	* 插入排序原理:
	* 从第二个元素开始,往回比较,比他大的元素往后挪,比他小那就把他放到比他小的那个数的后面
	* 时间复杂度为 O(n*n)
	*/

	DWORD start, end;
	start = timeGetTime();//开始排序

	for (int i = 1; i < arr.size(); ++i)
	{
		auto temp = arr[i];
		int j = i - 1;
		for (; j >= 0; --j)
		{
			if (arr[j] > temp) {
				swap(arr[j], arr[j + 1]);
			}
			else
			{
				break;
			}
		}
		arr[j + 1] = temp;
	}

	//for (auto i : arr)
	//{
	//	cout << i << " ";
	//}

		//排序结束
	end = timeGetTime() - start;
	cout << "插入排序用时(毫秒):" << end << endl;
}

void ShellSort(vectorarr)
{
	/*
	* 希尔排序原理:
	* 把数组分为子数组,子数组使用插入排序使得整个数组相对有序,从而下一轮插入排序消耗更小
	* 不稳定算法,时间复杂度不确定,最差为O(n*n)
	*/

	DWORD start, end;
	start = timeGetTime();//开始排序

	for (int gap = arr.size() / 2; gap > 0; gap /= 2) 
	{
		for (int i = gap; i < arr.size(); ++i)
		{
			auto temp = move(arr[i]);
			int j = i;
			for (; j >= gap && arr[j - gap] > temp; j -= gap) {
				arr[j] = move(arr[j - gap]);
			}
			arr[j] = move(temp);
		}
	}

	//for (auto i : arr)
	//{
	//	cout << i << " ";
	//}

		//排序结束
	end = timeGetTime() - start;
	cout << "希尔排序用时(毫秒):" << end << endl;
}

void percDown(vector&arr, int i, int n);
void HeapSort(vectorarr)
{
	/*
	* 堆排序原理:
	* 以数组构造堆,然后将堆中的数据取出放到另外一个数组,得到有序数组
	* 空间复杂度:O(n)  时间复杂度:O(nlog n)
	* 不具有稳定性
	*/

	DWORD start, end;
	start = timeGetTime();//开始排序

	//构造堆
	for (int i = arr.size() / 2 - 1; i >= 0; --i)
	{
		percDown(arr, i, arr.size());
	}

	for (int j = arr.size() - 1; j > 0; --j)
	{
		swap(arr[0], arr[j]);
		percDown(arr, 0, j);
	}

	//for (auto i : arr)
	//{
	//	cout << i << " ";
	//}

		//排序结束
	end = timeGetTime() - start;
	cout << "堆排序用时(毫秒):" << end << endl;
}

void mergeSort(vector&arr,vector&tempArr,int left,int right);
void merge(vector& arr, vector& tempArr, int leftPos, int rightPos, int rightEnd);
void MergeSort(vectorarr)
{
	DWORD start, end;
	start = timeGetTime();//开始排序

	vectortempArr(arr.size());
	mergeSort(arr, tempArr, 0, arr.size() - 1);

	//for (auto i : arr)
	//{
	//	cout << i << " ";
	//}

	//排序结束
	end = timeGetTime() - start;
	cout << "归并排序用时(毫秒):" << end << endl;
}

void quickSort(vector& ar, int left, int right);
void QuickSort(vectorarr)
{
	DWORD start, end;
	start = timeGetTime();//开始排序

	quickSort(arr, 0, arr.size() - 1);

	//for (auto i : arr)
	//{
	//	cout << i << " ";
	//}

	//排序结束
	end = timeGetTime() - start;
	cout << "快速排序用时(毫秒):" << end << endl;
}

void SortTest() {
	vector arr;
    //随机生成一个数组进行测试
	uniform_int_distributionu(0, 100000);
	default_random_engine e(time(0));
	for (int i = 0; i < 20000; ++i)
		arr.emplace_back(u(e));
	

	//for (auto i : arr)
	//{
	//	cout << i << " ";
	//}
	cout << endl;
	BubbleSort(arr);
	SelectionSort(arr);
	InsertionSort(arr);
	ShellSort(arr);
	HeapSort(arr);
	MergeSort(arr);
	QuickSort(arr);
}


int main() {

	SortTest();
}

void percDown(vector&arr, int i, int n) 
{
	//这是最大堆的下滤操作,将最大元素放到最上面

	//i表示要下滤的空洞,n表示堆中有多少个元素
	int child;
	int temp;

	for (temp = move(arr[i]); 2 * i + 1 < n; i = child)
	{
		//2*i+1表示结点i的左子节点(从0开始)
		//2*i+1& arr, vector& tempArr, int leftPos, int rightPos, int rightEnd)
{
	int leftEnd = rightPos - 1;
	int tmpPos = leftPos;
	int numElements = rightEnd - leftPos + 1;

	//从左右两个子数组中逐一比较将小的元素放到临时数组
	while (leftPos <= leftEnd && rightPos <= rightEnd)	
		if (arr[leftPos] <= arr[rightPos])
			tempArr[tmpPos++] = move(arr[leftPos++]);
		else 
			tempArr[tmpPos++] = move(arr[rightPos++]);	

	//将没有取完的数组剩下的元素放到临时数组
	while (leftPos <= leftEnd)	
		tempArr[tmpPos++] = move(arr[leftPos++]);

	while (rightPos <= rightEnd)
		tempArr[tmpPos++] = move(arr[rightPos++]);

	//将排好序的数组放回原数组中
	for (int i = 0; i < numElements; ++i, --rightEnd)
		arr[rightEnd] = move(tempArr[rightEnd]);
}

void mergeSort(vector& arr, vector& tempArr, int left, int right)
{
	if (right - left <= 10) //如果子数组太小可以直接用插入排序
	{
		for (int i = left+1; i <= right; ++i)
		{
			auto temp = arr[i];
			int j = i - 1;
			for (; j >= left; --j)
			{
				if (arr[j] > temp) {
					swap(arr[j], arr[j + 1]);
				}
				else
				{
					break;
				}
			}
			arr[j + 1] = temp;
		}
		return;
	}

	int center = (left + right) / 2;
	mergeSort(arr, tempArr, left, center);
	mergeSort(arr, tempArr, center + 1, right);
	merge(arr, tempArr, left, center + 1, right);
	
}

int median3(vector& arr, int left, int right) 
{
	//找到一个枢纽元素
	//要求首元素和枢纽元素和尾元素从小到大排列
	//然后将枢纽元素放到倒数第二位的位置

	int center = (right + left) / 2;
	if (arr[center] < arr[left])
		swap(arr[center], arr[left]);
	if (arr[right] < arr[left])
		swap(arr[right], arr[left]);
	if (arr[center] > arr[right])
		swap(arr[center], arr[right]);

	swap(arr[center], arr[right - 1]);
	return arr[right - 1];
}

void quickSort(vector& arr, int left, int right)
{
	if (left + 10 <= right)//如果数组较小就直接使用插入排序
	{
		int pivot = median3(arr, left, right);

		int i = left, j = right - 1;

		//实际上i从left+1的位开始,j从right-2的位置开始
		//因为left,right的元素大小必定符合要求
		for (;;)
		{
			while (arr[++i] < pivot) {}
			while (pivot < arr[--j]) {}
			if (i < j)
				swap(arr[i], arr[j]);
			else
				break;
		}

		swap(arr[i], arr[right - 1]);//恢复枢纽元素

		//将枢纽元素左边和右边的元素进行排序
		quickSort(arr, left, i - 1);
		quickSort(arr, i + 1, right);
	}
	else
	{
		for (int i = left + 1; i <= right; ++i)
		{
			auto temp = arr[i];
			int j = i - 1;
			for (; j >= left; --j)
			{
				if (arr[j] > temp) {
					swap(arr[j], arr[j + 1]);
				}
				else
				{
					break;
				}
			}
			arr[j + 1] = temp;
		}
		return;
	}
}

七大排序算法_第1张图片

 

你可能感兴趣的:(C++,排序算法,算法,数据结构,visual,studio,c++)