排序是将一组”无序”的记录序列调整为”有序”的记录序列。

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。

冒泡排序:依次比较相邻的两个数,按照从小到大或者从大到小的顺序进行交换。

插入排序:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。

选择排序:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

希尔排序:先将整个待排序记录序列分割成若干个子序列,再在子序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。

归并排序:采用分治法,通过对若干个有序结点序列的归并来实现排序。所谓归并是指将若干个已排好序的部分合并成一个有序的部分。

堆排序:是一个完全二叉树。

快速排序:采用分治法,使数组中的每个元素与基准值比较,数组中比基准值小的放在基准值的左边,形成左部;大的放在右边,形成右部;接下来将左部和右部分别递归地执行上面的过程。

std::sort(std::stable_sort):类似于快速排序。

各种排序算法的时间复杂度如下:

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "sort.hpp"
#include <iostream>
#include <vector>
#include <algorithm>

const std::vector<int> array_src{ 12, -32, 138, -54, 34, 87, 200, -1, -901, 88 };

static void print_result(const std::vector<int>& vec)
{
	for (int i = 0; i < vec.size(); i++)
		fprintf(stderr, "%d  ", vec[i]);
	fprintf(stderr, "\n");
}

int test_sort_bubble() // 冒泡排序
{
	// reference: http://mathbits.com/MathBits/CompSci/Arrays/Bubble.htm
	std::vector<int> vec(array_src.begin(), array_src.end());
	int tmp = 0;

	for (int i = 1; i < vec.size(); i++) {
		for (int j = 0; j < vec.size() - 1; j++) {
			if (vec[j + 1] < vec[j]) {
				tmp = vec[j];
				vec[j] = vec[j + 1];
				vec[j + 1] = tmp;
			}
		}
	}

	fprintf(stderr, "bubble sort result: \n");
	print_result(vec);

	return 0;
}

int test_sort_insertion() // 插入排序
{
	// reference: http://cforbeginners.com/insertionsort.html
	std::vector<int> vec(array_src.begin(), array_src.end());
	int tmp = 0, j = 0;

	for (int i = 1; i < vec.size(); i++){
		j = i;

		while (j > 0 && vec[j] < vec[j - 1]){
			tmp = vec[j];
			vec[j] = vec[j - 1];
			vec[j - 1] = tmp;
			j--;
		}
	}

	fprintf(stderr, "insertion sort result: \n");
	print_result(vec);

	return 0;
}

int test_sort_selection() // 选择排序
{
	// reference: http://mathbits.com/MathBits/CompSci/Arrays/Selection.htm
	std::vector<int> vec(array_src.begin(), array_src.end());
	int tmp = 0;

	for (int i = vec.size() - 1; i > 0; i--) {
		int first = 0;
		for (int j = 1; j <= i; j++) {
			if (vec[j] > vec[first])
				first = j;
		}

		tmp = vec[first];
		vec[first] = vec[i];
		vec[i] = tmp;
	}

	fprintf(stderr, "selection sort result: \n");
	print_result(vec);

	return 0;
}

int test_sort_shell() // 希尔排序
{
	// reference: http://www.cplusplus.com/forum/general/123961/
	std::vector<int> vec(array_src.begin(), array_src.end());
	int tmp = 0, gap = 0;

	for (int gap = vec.size() / 2; gap > 0; gap /= 2) {
		for (int i = gap; i < vec.size(); i++) {
			for (int j = i - gap; j >= 0 && vec[j] > vec[j + gap]; j -= gap) {
				tmp = vec[j];
				vec[j] = vec[j + gap];
				vec[j + gap] = tmp;
			}
		}
	}

	fprintf(stderr, "shell sort result: \n");
	print_result(vec);

	return 0;
}

// left is the index of the leftmost element of the subarray
// right is one past the index of the rightmost element
static void merge(std::vector<int>& vecSrc, int left, int right, std::vector<int>& vecDst)
{
	// base case: one element
	if (right == left + 1) {
		return;
	} else {
		int i = 0;
		int length = right - left;
		int midpoint_distance = length / 2;
		/* l and r are to the positions in the left and right subarrays */
		int l = left, r = left + midpoint_distance;

		/* sort each subarray */
		merge(vecSrc, left, left + midpoint_distance, vecDst);
		merge(vecSrc, left + midpoint_distance, right, vecDst);

		/* merge the arrays together using scratch for temporary storage */
		for (i = 0; i < length; i++) {
			/* Check to see if any elements remain in the left array; if so,
			* we check if there are any elements left in the right array; if
			* so, we compare them.  Otherwise, we know that the merge must
			* use take the element from the left array */
			if (l < left + midpoint_distance && (r == right || std::min(vecSrc[l], vecSrc[r]) == vecSrc[l])) {
				vecDst[i] = vecSrc[l];
				l++;
			} else {
				vecDst[i] = vecSrc[r];
				r++;
			}
		}
		/* Copy the sorted subarray back to the input */
		for (i = left; i < right; i++) {
			vecSrc[i] = vecDst[i - left];
		}
	}
}

int test_sort_merge() // 归并排序
{
	// reference: http://www.cprogramming.com/tutorial/computersciencetheory/merge.html
	std::vector<int> vecSrc(array_src.begin(), array_src.end());
	std::vector<int> vecDst(array_src.size());

	merge(vecSrc, 0, vecSrc.size(), vecDst);

	fprintf(stderr, "merge sort result: \n");
	print_result(vecDst);

	return 0;
}

static void quick(std::vector<int>& vec, int left, int right)
{
	int i = left, j = right;
	int tmp;
	int pivot = vec[(left + right) / 2];

	// partition
	while (i <= j) {
		while (vec[i] < pivot)
			i++;
		while (vec[j] > pivot)
			j--;
		if (i <= j) {
			tmp = vec[i];
			vec[i] = vec[j];
			vec[j] = tmp;
			i++;
			j--;
		}
	};

	// recursion
	if (left < j)
		quick(vec, left, j);
	if (i < right)
		quick(vec, i, right);
}

int test_sort_quick() // 快速排序
{
	// reference: http://www.algolist.net/Algorithms/Sorting/Quicksort
	std::vector<int> vec(array_src.begin(), array_src.end());

	quick(vec, 0, vec.size() - 1);

	fprintf(stderr, "quick sort result: \n");
	print_result(vec);

	return 0;
}

static void max_heapify(std::vector<int>& vec, int i, int n)
{
	int temp = vec[i];
	int j = 2 * i;

	while (j <= n) {
		if (j < n && vec[j + 1] > vec[j])
			j = j + 1;

		if (temp > vec[j]) {
			break;
		} else if (temp <= vec[j]) {
			vec[j / 2] = vec[j];
			j = 2 * j;
		}
	}

	vec[j / 2] = temp;
}

static void heapsort(std::vector<int>& vec, int n)
{
	for (int i = n; i >= 2; i--) {
		int temp = vec[i];
		vec[i] = vec[1];
		vec[1] = temp;

		max_heapify(vec, 1, i - 1);
	}
}

static void build_maxheap(std::vector<int>& vec, int n)
{
	for (int i = n / 2; i >= 1; i--)
		max_heapify(vec, i, n);
}

int test_sort_heap() // 堆排序
{
	// reference: http://proprogramming.org/heap-sort-in-c/
	std::vector<int> vec(array_src.begin(), array_src.end());
	vec.insert(vec.begin(), -1);

	build_maxheap(vec, vec.size()-1);
	heapsort(vec, vec.size()-1);

	std::vector<int> vecDst(vec.begin() + 1, vec.end());
	fprintf(stderr, "heap sort result: \n");
	print_result(vecDst);

	return 0;
}

static bool cmp(int i, int j)
{
	return (i<j);
}

int test_sort_STL() // std::sort
{
	// reference: http://www.cplusplus.com/reference/algorithm/sort/
	std::vector<int> vec(array_src.begin(), array_src.end());

	std::sort(vec.begin(), vec.end(), cmp);

	fprintf(stderr, "STL sort result: \n");
	print_result(vec);

	std::vector<int> vec1(array_src.begin(), array_src.end());

	std::stable_sort(vec1.begin(), vec1.end(), cmp);

	fprintf(stderr, "STL stable sort result: \n");
	print_result(vec1);

	return 0;
}

GitHubhttps://github.com/fengbingchun/Messy_Test

常用排序算法的C++实现的更多相关文章

  1. Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法

    Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排 ...

  2. 转载部长一篇大作:常用排序算法之JavaScript实现

    转载部长一篇大作:常用排序算法之JavaScript实现 注:本文是转载实验室同门王部长的大作,找实习找工作在即,本文颇有用处!原文出处:http://www.cnblogs.com/ywang172 ...

  3. Java 常用排序算法/程序员必须掌握的 8大排序算法

    Java 常用排序算法/程序员必须掌握的 8大排序算法 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配 ...

  4. 常用排序算法的python实现和性能分析

    常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...

  5. 面试中常用排序算法实现(Java)

    当我们进行数据处理的时候,往往需要对数据进行查找操作,一个有序的数据集往往能够在高效的查找算法下快速得到结果.所以排序的效率就会显的十分重要,本篇我们将着重的介绍几个常见的排序算法,涉及如下内容: 排 ...

  6. 常用排序算法java实现

    写在前面:纸上得来终觉浅.基本排序算法的思想,可能很多人都说的头头是到,但能说和能写出来,真的还是有很大区别的. 今天整理了一下各种常用排序算法,当然还不全,后面会继续补充.代码中可能有累赘或错误的地 ...

  7. 我们一起来排序——使用Java语言优雅地实现常用排序算法

    破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...

  8. Python实现常用排序算法

    Python实现常用排序算法 冒泡排序 思路: 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完 ...

  9. 第四百一十五节,python常用排序算法学习

    第四百一十五节,python常用排序算法学习 常用排序 名称 复杂度 说明 备注 冒泡排序Bubble Sort O(N*N) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...

  10. Java常用排序算法及性能测试集合

    测试报告: Array length: 20000 bubbleSort : 573 ms bubbleSortAdvanced : 596 ms bubbleSortAdvanced2 : 583 ...

随机推荐

  1. 使用matlab对图像进行傅里叶变换

    原图: (0) 代码: I=imread('1.jpg'); I=rgb2gray(I); I=im2double(I); F=fft2(I); F=fftshift(F); F=abs(F); T= ...

  2. JQuery获取和设置Select选项的常用方法总结

    1.获取select 选中的 text:  $("#cusChildTypeId").find("option:selected").text();  $(&q ...

  3. Join Resig's “Simple JavaScript Inheritance ”

    ======================Enein翻译=========================           John Resig 写了一篇关于 JavaScript 里类似其它语 ...

  4. Yii 不完全解决方案(一)

    此文意在记录 Yii 开发过程中的小问题解决方案 1. Yii 中 Js 和 Css 文件的引入. 我们就从最简单的问题开始吧,说起来也不是问题,只是语法罢了.假设我们的 js 文件都放在和 prot ...

  5. 二十、在Intellij IDEA中使用Debug

    Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方 ...

  6. 使用Spring实现AOP(XML+注解)

    一.Spring对AOP的支持 AOP并不是Spring框架特有的,Spring只是支持AOP编程的框架之一,每一个框架对AOP的支持各有特点,有些AOP能够对方法的参数进行拦截,有些AOP对方法进行 ...

  7. ffmpeg 简单使用总结

    FFMPEG 生成指定长度的空白音频: ffmpeg -f lavfi -i aevalsrc=0 -t seconds -q:a 9 -acodec libmp3lame out.mp3 FFMPE ...

  8. Spring知识点小结(二)

    一.配置非自定义的Bean(数据源DataSource模型) DBCP数据源:        导入dbcp的jar包:dbcp+pool+connector                代码实现:  ...

  9. #leetcode刷题之路35-搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置.你可以假设数组中无重复元素. 示例 1:输入: [1,3,5,6], 5输出: ...

  10. 【模板】负环(spfa)

    题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 输入输出格式 输入格式: 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个顶点,M条边 ...