一、引言
对于各种排序算法也算是有了一定的了解,所以这里做一个总结。
二、冒泡排序法。
这是比较经典的排序算法,主要是通过内外两层的循环比较,使得乱序变为顺序。
下面是一个测试代码

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) (这里只是考虑了互换操作), 比冒泡排序法快
稳定性:不稳定
