常用排序算法的C++实现
排序是将一组”无序”的记录序列调整为”有序”的记录序列。
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,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; }
GitHub:https://github.com/fengbingchun/Messy_Test
常用排序算法的C++实现的更多相关文章
- Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法
Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排 ...
- 转载部长一篇大作:常用排序算法之JavaScript实现
转载部长一篇大作:常用排序算法之JavaScript实现 注:本文是转载实验室同门王部长的大作,找实习找工作在即,本文颇有用处!原文出处:http://www.cnblogs.com/ywang172 ...
- Java 常用排序算法/程序员必须掌握的 8大排序算法
Java 常用排序算法/程序员必须掌握的 8大排序算法 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配 ...
- 常用排序算法的python实现和性能分析
常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...
- 面试中常用排序算法实现(Java)
当我们进行数据处理的时候,往往需要对数据进行查找操作,一个有序的数据集往往能够在高效的查找算法下快速得到结果.所以排序的效率就会显的十分重要,本篇我们将着重的介绍几个常见的排序算法,涉及如下内容: 排 ...
- 常用排序算法java实现
写在前面:纸上得来终觉浅.基本排序算法的思想,可能很多人都说的头头是到,但能说和能写出来,真的还是有很大区别的. 今天整理了一下各种常用排序算法,当然还不全,后面会继续补充.代码中可能有累赘或错误的地 ...
- 我们一起来排序——使用Java语言优雅地实现常用排序算法
破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...
- Python实现常用排序算法
Python实现常用排序算法 冒泡排序 思路: 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完 ...
- 第四百一十五节,python常用排序算法学习
第四百一十五节,python常用排序算法学习 常用排序 名称 复杂度 说明 备注 冒泡排序Bubble Sort O(N*N) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...
- Java常用排序算法及性能测试集合
测试报告: Array length: 20000 bubbleSort : 573 ms bubbleSortAdvanced : 596 ms bubbleSortAdvanced2 : 583 ...
随机推荐
- [原]如何在Android用FFmpeg+SDL2.0之同步音频
同步音频的原理可以参考:http://dranger.com/ffmpeg/tutorial05.html 本文是在 [原]如何在Android用FFmpeg+SDL2.0之同步视频 的基础上面继续 ...
- 随机以及时间相关函数——C语言描述
随机相关的函数 头文件 stdlib.h 相关函数 :rand .srand rand( rand C++ Reference ) 函数声明:int rand( void ); rand函数返回一个位 ...
- itext-2.1.7.jar
iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库.通过iText不仅可以生成PDF或rtf的文档,而且可以将XML.Html文件转化为PDF文件. ...
- Html 列表实现展开和收起
HTML中,点击列表元素,在其下展开更多的小选项.不点的时候是收起来的.就是实现路由器左边的菜单那样的功能.怎么实现,知道的指点一下,谢谢了!! 最常见的方法是通过Javascript控制某标签的CS ...
- [19/03/26-星期二] 容器_Map(图、键值对、映射)接口之HashMap(散列映射)&TreeMap(树映射)
一.概念&方法 现实生活中,我们经常需要成对存储某些信息.比如,我们使用的微信,一个手机号只能对应一个微信账户,这就是一种成对存储的关系. Map就是用来存储“键(key)-值(value) ...
- Softmax回归(Softmax Regression, K分类问题)
Softmax回归:K分类问题, 2分类的logistic回归的推广.其概率表示为: 对于一般训练集: 系统参数为: Softmax回归与Logist ...
- openmax component类的继承关系
向OpenCORE里继承一个新的codec时,需要用到OpenMAX接口规范对该codec进行封装,即要定义一个用于封装的类(wrapper),实现OpenMAX规定的集中核心方法(omx core ...
- 嵌入式 Linux 学习 之路
1. 嵌入式 Linux (首先百度了一下) 结果没有 看到 有信息的内容.2017年2月17日10:06:51 (嵌入式Linux 英文名:embedded Linux 简称 eLinux,Git ...
- 工具 | Axure基础操作 No.3
下午了,再来补一些学习,今天东西不多哦,感觉慢慢上手了. 1.设置元件禁用状态 2.设置单选按钮唯一选中 注意这里在浏览器中就只能唯一选中了. 3.设置图片上的文字 4.图片的切割和裁剪 5.嵌入多媒 ...
- TCP/IP初识(一)
TCP/IP学习记录,如有错误请指正,谢谢!!! 什么是TCP/IP协议? TCP/IP协议族分为四层(另一个名字是Internet协议族(Internet Protocol Suite)):链路层. ...