经典排序算法的C++实现

文章介绍了冒泡排序、选择排序、插入排序、归并排序、快速排序和堆排序六种常见的排序算法,分别给出了C++的实现代码,并通过测试程序展示了它们在处理10000个随机整数时的时间消耗,归并排序和快速排序表现出较高的效率。
摘要由CSDN通过智能技术生成

1. 冒泡排序

  • 时间复杂度:O(n^2),相等元素的相对排序不会改变(稳定)
  • C++实现如下
void BubbleSort(vector<int>& vec)
{
	int num = vec.size();
	for (int i = 0; i < num; i++) {
		for (int j = 0; j < num - i - 1; j++) {
			if (vec[j] > vec[j + 1]) {
				int temp = vec[j];
				vec[j] = vec[j + 1];
				vec[j + 1] = temp;
			}
		}
	}
}

2. 选择排序

  • 时间复杂度:O(n^2),相等元素的相对排序可能发生改变(不稳定)
  • C++实现如下
void SelectSort(vector<int>& vec)
{
	int num = vec.size();
	for (int i = 0; i < num - 1; i++) {
		int min_idx = i;
		for (int j = i + 1; j < num; j++) {
			if (vec[min_idx] > vec[j]) {
				min_idx = j;
			}
		}
		if (min_idx != i) {
			int temp = vec[i];
			vec[i] = vec[min_idx];
			vec[min_idx] = temp;
		}
	}
}

3. 插入排序

  • 时间复杂度:O(n^2),相等元素的相对排序不会改变(稳定)
  • C++实现如下
void InsertSort(vector<int>& vec)
{
	int num = vec.size();
	for (int i = 1; i < num; i++) {
		int idx = i;
		int val = vec[i];
		while (idx > 0 && vec[idx - 1] > val) {
			vec[idx] = vec[idx - 1];
			idx--;
		}
		vec[idx] = val;
	}
}

4. 归并排序

  • 时间复杂度:O(n*log(n)),相等元素的相对排序不会改变(稳定)
  • C++实现如下
vector<int> _MergeSort(vector<int>& v, int left, int right)
{
	vector<int> ret;
	if (left == right) {
		ret.emplace_back(v[left]);
		return ret;
	}

	int mid = (left + right) / 2;
	vector<int> v1 = _MergeSort(v, left, mid);
	vector<int> v2 = _MergeSort(v, mid + 1, right);

	int idx1 = 0;
	int idx2 = 0;
	int cnt = 0;
	ret.resize(v1.size() + v2.size());

	while (idx1 < v1.size() && idx2 < v2.size()) {
		if (v1[idx1] <= v2[idx2]) {
			ret[cnt++] = v1[idx1++];
		}
		else {
			ret[cnt++] = v2[idx2++];
		}
	}

	if (idx1 < v1.size()) {
		for (int i = idx1; i < v1.size(); i++) {
			ret[cnt++] = v1[idx1++];
		}
	}
	else {
		for (int i = idx2; i < v2.size(); i++) {
			ret[cnt++] = v2[idx2++];
		}
	}
	return ret;
}

void MergeSort(vector<int>& vec)
{
	int num = vec.size();
	if (num == 0) {
		return;
	}
	vec = _MergeSort(vec, 0, num - 1);
}

5. 快速排序

  • 时间复杂度:O(n*log(n)),相等元素的相对排序可能发生改变(不稳定)
  • C++实现如下
void _QuickSort(vector<int>& v, int low, int high)
{
	if (low >= high) {
		return;
	}

	int start = low;
	int end = high;
	int val = v[start];
	while (start < end) {
		while (start < end && val <= v[end]) {
			end--;
		}
		v[start] = v[end];
		while (start < end && v[start] <= val) {
			start++;
		}
		v[end] = v[start];
	}

	// When the index start meets the index end, set the meeting position
	// as the index pivot. After this, all values in [low, pivot) are not bigger
	// than val, and all values in (pivot, high] are not smaller than val.
	int pivot = start;
	v[pivot] = val;

	_QuickSort(v, low, pivot - 1);
	_QuickSort(v, pivot + 1, high);
}

void QuickSort(vector<int>& vec)
{
	int num = vec.size();
	if (num == 0) {
		return;
	}
	_QuickSort(vec, 0, num - 1);
}

6. 堆排序

  • 时间复杂度:O(n*log(n)),相等元素的相对排序可能发生改变(不稳定)
  • C++实现如下
void _AdjustHeap(vector<int>& v, int parent, int last)
{
	int leftChild = 2 * parent + 1;
	while (leftChild <= last) {
		int rightChild = leftChild + 1;

		int largerIdx;
		if (rightChild <= last && v[leftChild] < v[rightChild]) {
			largerIdx = rightChild;
		}
		else {
			largerIdx = leftChild;
		}

		if (v[parent] < v[largerIdx]) {
			int val = v[parent];
			v[parent] = v[largerIdx];
			v[largerIdx] = val;

			parent = largerIdx;
			leftChild = 2 * parent + 1;
		}
		else {
			break;
		}
	}
}

void HeapSort(vector<int>& vec)
{
	int last = vec.size() - 1;
	int parent = (last - 1) / 2;

	// Initialize the heap, where the root node (the first one)
	// is the largest value.
	while (parent >= 0) {
		_AdjustHeap(vec, parent, last);
		parent--;
	}

	// Put the largest value of the heap (the first one) to the end,
	// and readjust the heap.
	while (last >= 0) {
		int val = vec[last];
		vec[last] = vec[0];
		vec[0] = val;

		last--;
		_AdjustHeap(vec, 0, last);
	}
}

附:各排序算法的耗时测试

  • C++测试代码如下
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;

void Print(string prefix, vector<int>& vec)
{
	cout << prefix << endl;
	for (int i = 0; i < min(10, int(vec.size())); i++) {
		cout << vec[i] << " ";
	}
	if (vec.size() > 10) {
		cout << "...";
	}
	cout << endl;
}

int main()
{
	int num = 10000;
	clock_t start, end;

	vector<int> vec;
	vec.reserve(num);
	for (int i = 0; i < num; i++) {
		vec.emplace_back(rand() % num);
	}
	Print("original data:", vec);

	vector<int> v1;
	v1.resize(num);
	copy(vec.begin(), vec.end(), v1.begin());
	start = clock();
	BubbleSort(v1);
	end = clock();
	Print("\nbubble sort:", v1);
	cout << "time cost: " << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl; // 0.862s

	vector<int> v2;
	v2.resize(num);
	copy(vec.begin(), vec.end(), v2.begin());
	start = clock();
	SelectSort(v2);
	end = clock();
	Print("\nselect sort:", v2);
	cout << "time cost: " << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl; // 0.407s

	vector<int> v3;
	v3.resize(num);
	copy(vec.begin(), vec.end(), v3.begin());
	start = clock();
	InsertSort(v3);
	end = clock();
	Print("\ninsert sort:", v3);
	cout << "time cost: " << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl; // 0.279s

	vector<int> v4;
	v4.resize(num);
	copy(vec.begin(), vec.end(), v4.begin());
	start = clock();
	MergeSort(v4);
	end = clock();
	Print("\nmerge sort:", v4);
	cout << "time cost: " << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl; // 0.026s

	vector<int> v5;
	v5.resize(num);
	copy(vec.begin(), vec.end(), v5.begin());
	start = clock();
	QuickSort(v5);
	end = clock();
	Print("\nquick sort:", v5);
	cout << "time cost: " << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl; // 0.002s

	vector<int> v6;
	v6.resize(num);
	copy(vec.begin(), vec.end(), v6.begin());
	start = clock();
	HeapSort(v6);
	end = clock();
	Print("\nheap sort:", v6);
	cout << "time cost: " << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl; // 0.004s

	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值