排序算法总结(C++版本)
Posted fantianliang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法总结(C++版本)相关的知识,希望对你有一定的参考价值。
一、引言
对于各种排序算法也算是有了一定的了解,所以这里做一个总结。
二、冒泡排序法。
这是比较经典的排序算法,主要是通过内外两层的循环比较,使得乱序变为顺序。
下面是一个测试代码
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 int main() 5 { 6 vector<int> L(10); 7 for(int i=0;i<L.size();i++) 8 { 9 L[i] = 10 - i; 10 } 11 int temp = 0; 12 for (int i = 0; i < L.size(); i++) 13 for (int j = L.size()-1; j >= (i+1); j--) 14 { 15 if (L[j-1] > L[j ]) 16 { 17 temp = L[j]; 18 L[j] = L[j - 1]; 19 L[j - 1] = temp; 20 } 21 } 22 for (int j = 0; j < L.size(); j++) 23 { 24 cout << "the number is " << L[j] << endl; 25 } 26 }
初始化为10-1,最后冒泡排序法的的结果为升序排列。
下面是算法的运行过程。
在第一次循环里面(即i=0的时候):
每一次比较之后数据变化如下:
随着 i 的增大,蓝色区域扩展如下:
最后达到有序状态。
从上面的分析可以看出来:
其时间复杂度:O(n 2) (这里的时间,主要花费在了比较运算上面,所以计算的是循环里面的比较次数)
空间复杂度: O(n) (即所有的变量占用的空间)
算法稳定性上来说,属于稳定算法(即两个相同的元素经过排序之后的 先后顺序不变)。
二直接插入排序
插入排序的算法思想是,将待排序的数据看做两个部分,一部分是有序数据A,一部分是无序数据B, 最开始的时候A的规模是0, B是整个的待排序数据。
之后对于B中的每一个数据,按照顺序插入到A中,直至整个过程完成。
例如,对于一个待排序数组来说,过程如下:
#include <iostream> using namespace std; void Sorted(int* x, int length); int main(void) { int a[5]={2,1,3,6,4}; Sorted(a,5); for(int i=0;i<5;i++) cout<<"-----------"<<a[i]<<endl; return 0; } void Sorted(int* x, int length) { for(int i=1; i<length;i++ ) { int temp=x[i]; int j=i-1; while( j>=0 && temp<x[j]) { x[j+1]=x[j]; x[j]=temp; j--; } } }
在上面的例子里面:
1 a[5]={2,1,3,6,4};
在每一步的运算过程中,其数据的变化如下:
上述描述了比较的过程。
柱状图表表示了每一个位置的数字大小,蓝色区域为无序部分,黄色部分为经过一次运算之后的有序部分。
其主要步骤是,选择无序部分的第一个元素,将其插入到黄色的有序部分里面去,这样黄色区域扩展,而蓝色区域则是不断地减小,直至所有的区域变为有序状态。
复杂度分析:
可以看到,上述过程,主要操作是比较操作,然后是赋值操作,其中赋值操作的所花费的时间更长
在最好的情况下,整个数据正好是升序排列的,这个时候比较操作是(n-1),赋值操作 复杂度为0
在最坏的情况下,整个数据是降序排列的,这个时候比较次数是 n*(n-1)/2 次,赋值操作是4*n*(n-1)/2, 主要的时间花在了赋值的操作上,时间复杂度为O(n2)
稳定性来说,这个算法是不稳定的,即相同的两个元素,在排序前和排序之后,先后次序可能发生了改变。
三、选择排序
选择排序的思想与上面的插入排序相同,将数据分为有序部分和无序部分。
在无序部分里面选择出最值(比如说是最大值,放到有序部分),这样经过不断的选择无序部分的最大值,使得有序部分不断的扩展,无序部分不断地缩小,最后得到整个有序数据序列。
具体代码如下:
1 #include <iostream> 2 using namespace std; 3 void Sorted(int* x, int length); 4 int main(void) 5 { 6 int a[5] = { 4,1,3,2,6}; 7 Sorted(a, 5); 8 for (int i = 0; i < 5; i++) 9 cout << "-----------" << a[i] << endl; 10 return 0; 11 } 12 13 void Sorted(int* x, int length) 14 { 15 int max = 0; 16 int len = length - 1; 17 18 for (int i = 0; i <= length-1; i=i+1) 19 { 20 max = x[0]; 21 int j = 0; 22 int number = 0; 23 for (j = 1; j <= len; j++) 24 { 25 if (max < x[j]) 26 { 27 max = x[j]; 28 number = j; 29 } 30 } 31 int temp = x[len]; 32 x[len] = max; 33 x[number] = temp; 34 len--; 35 } 36 }
其每一次的比较过程如下:
如图可以看到,有序的黄色区域在不断的扩展,无序部分在逐渐减少。
复杂度:
最好情况:全是升序排列,这个时候只需要(n-1)次比较
最坏情况:全是降序排列,这个时候需要(n-1)*n/2次比较,(n-1)次互换操作,时间复杂度在O(n) (这里只是考虑了互换操作), 比冒泡排序法快
稳定性:不稳定
以上是关于排序算法总结(C++版本)的主要内容,如果未能解决你的问题,请参考以下文章