排序算法总结(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 }
View Code

  初始化为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--;
        }
     } 
}
View Code

  在上面的例子里面:

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 }
View Code

 

其每一次的比较过程如下:

技术图片 技术图片技术图片

技术图片技术图片技术图片

 

如图可以看到,有序的黄色区域在不断的扩展,无序部分在逐渐减少。

复杂度:

  最好情况:全是升序排列,这个时候只需要(n-1)次比较

  最坏情况:全是降序排列,这个时候需要(n-1)*n/2次比较,(n-1)次互换操作,时间复杂度在O(n) (这里只是考虑了互换操作), 比冒泡排序法快

  稳定性:不稳定

 

  

 

 

以上是关于排序算法总结(C++版本)的主要内容,如果未能解决你的问题,请参考以下文章

内部排序算法总结(上)C++实现

七种常见经典排序算法总结(C++)

C++算法之——常用算法总结

算法笔记 排序算法完整介绍及C++代码实现 HERODING的算法之路

内部排序算法总结(下)C++实现

排序算法总结 一