C++|关于各种排序的总结


排序算法应该是所有学习编程语言的新手第一个接触到的算法,本文主要介绍这些排序方法在C++中如何实现。

排序算法主要有:

  1. 选择排序
  2. 冒泡排序
  3. 插入排序
  4. 快速排序
  5. 希尔排序
  6. 桶排序

以下逐一介绍这些排序方法。

1.选择排序

这种排序方式比较容易理解,利用循环,每次找一个元素放在它最终的位置上,比如先找到最小的元素,放在首位,然后再剩下的元素中找到最小的,依此类推,最终从小到大排好。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int n, a[10001], k;
 9     cin >> n;
10     for (int i = 0; i < n; i++)
11     {
12         cin >> a[i];    //输入数据
13     }
14 
15     for (int i = 0; i < n; i++)
16     {
17         k = i;  //  设置这一次确定哪一位
18         for (int j = i; j < n; j++) //嵌套一个循环,找到最小的那一个
19         {
20             if (a[j] < a[k])
21             {
22                 k = j;
23             }
24         }
25 
26         swap(a[i], a[k]);   //把这次循环最小的(需要的)搞到前面来,也就是搞到它应该在的位置
27     }
28 
29     for (int i = 0; i < n; i++)
30     {
31         cout << a[i] << ' ';    //输出数据
32     }
33     cout << endl;
34 
35     system("pause");
36     return 0;
37 }
选择排序

 2.冒泡排序

这是另一种常见的排序方式,通过对违反顺序的相邻元素进行调整以达成目标,假设需要从小到大进行排序,那么每次循环都会从头开始比较相邻两个元素的大小,小的放在前面,大的放在后面,一轮结束后,最大的元素(泡)便被“冒”到了最后。每次循环都是如此。

在循环中可以加一个终止条件:如果一轮下来后没有过调整次序,那么说明已经排序完毕,跳出循环即可。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int n, a[10001];
 9     bool flag;  //用于记录一次循环中有没有发生过元素交换
10 
11     cin >> n;
12     for (int i = 0; i < n; i++)
13     {
14         cin >> a[i];    //输入数据
15     }
16 
17     for (int i = 1; i < n; i++)     //注意这个循环只有(n-1)次
18     {
19         flag = false;   //一开始先设置flag为false
20         for (int j = 0 ; j < n - i; j++)
21         {
22             if (a[j] > a[j + 1])
23             {
24                 swap(a[j], a[j + 1]);   //相邻的进行比较,并调整
25                 flag = true;
26             }
27         }
28         //cout << a[i] << ' ';
29         if (!flag)  //若无调整,则跳出循环
30             break;
31     }
32 
33     for (int i = 0; i < n; i++)
34     {
35         cout << a[i] << ' ';    //输出数据
36     }
37     cout << endl;
38     system("pause");
39     return 0;
40 }
冒泡排序

3.插入排序(直接插入排序)

插入排序,顾名思义,是将新的元素插入到原来已经排列好的一组数中。在具体实现时,可以将数组分为两部分。第一部分是除最后一位的其它所有元素,并且给出一个空间,使得可以让第二部分中的待插入元素有位置;第二部分是待插入的元素。第一部分排完序后,操作第二部分。

原理流程如下动图所示(侵删):

虽然插入排序和选择排序的时间复杂度一样,但是插入排序的第二重循环可以提前结束,不需要遍历到开始位置。尤其是对于已经快要排列好的数组。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 void insertSelectionSort(int arr[], int n)  //这种排序不需要用swap交换语句,只需要复制即可
 7 {
 8     for (int i = 1; i < n; i++)     //插入排序在进行时不需要考虑第一个数的情况,一个数,必然有序
 9     {
10         int key = arr[i];   //取出待排序的数
11         int j;
12         for (j = i; j > 0 && arr[j - 1] > key; j--)     //有两个限制条件,第二个限制条件使得插入排序比选择排序高效
13             arr[j] = arr[j - 1];
14         
15         arr[j] = key;
16     }
17 }
18 
19 int main()
20 {
21     int n, a[10001];
22 
23     cin >> n;
24     for (int i = 0; i < n; i++)
25     {
26         cin >> a[i];    //输入数据
27     }
28 
29     insertSelectionSort(a, n);
30 
31     for (int i = 0; i < n; i++)
32     {
33         cout << a[i] << ' ';    //输出数据
34     }
35     cout << endl;
36 
37     system("pause");
38     return 0;
39 }
插入排序

4.快速排序

快速排序是一种相当高效的算法,主要采用的分治的思想方法。一次排序过后,确立一个枢轴,放在某个位置,让左边的数都小于它,右边的数都大于它。

主要是搞清一轮探测到底要达成什么目的,上下的只需要递归即可。

取一左一右向中间慢慢移动,一旦发现有前大于后,就交换,知道两者相碰,设置第一个数作为枢轴,开始递归。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 void quickSort(int left, int right, int arr[])
 7 {
 8     if(left >= right)
 9         return;
10     
11     int i, j, base;
12     i = left, j = right;
13     base = arr[left];  //取最左边的数为基准数
14     while (i < j)
15     {
16         while (arr[j] >= base && i < j)
17             j--;
18         while (arr[i] <= base && i < j)
19             i++;
20         if(i < j)
21             swap(arr[i], arr[j]);
22     }
23 
24     //基准数归位
25     arr[left] = arr[i];
26     arr[i] = base;
27 
28     //一轮基本探测已结束
29 
30     quickSort(left, i - 1, arr);    //递归左边
31     quickSort(i + 1, right, arr);   //递归右边
32 }
33 
34 int main()
35 {
36     int n, a[10001];
37 
38     cin >> n;
39     for (int i = 0; i < n; i++)
40     {
41         cin >> a[i];    //输入数据
42     }
43 
44     quickSort(0, n - 1, a);
45 
46     for (int i = 0; i < n; i++)
47     {
48         cout << a[i] << ' ';    //输出数据
49     }
50     cout << endl;
51 
52     system("pause");
53     return 0;
54 }
快速排序

5.希尔排序

希尔排序是在不相邻的元素之间进行交换等操作。

关键是增量gap的设置,每次一轮下来之后,gap都要相应地减小,本文给出的例子是变为原来的1/2。对于每一轮,内部都是用插入排序。直到gap最后一次是1时插入排序完,便得到了最终的结果。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int Dgap = 2;
 7 
 8 void shellSort(int arr[], int len)
 9 {
10     int insertNumber = 0;
11     int gap = len / Dgap;    //必须保证此时gap不小于1,否则无法进入while循环
12     while (gap >= 1)
13     {
14         for (int i = gap; i < len; i++)
15         {
16             insertNumber = arr[i];
17             int j = i;
18             while (j >= gap && insertNumber < arr[j - gap])
19             {
20                 arr[j] = arr[j - gap];
21                 j -= gap;
22             }
23             arr[j] = insertNumber;
24         }
25         gap /= Dgap;
26     }
27 }
28 
29 int main()
30 {
31     int n, a[10001];
32 
33     cin >> n;
34     for (int i = 0; i < n; i++)
35     {
36         cin >> a[i];    //输入数据
37     }
38 
39     shellSort(a, n);
40 
41     for (int i = 0; i < n; i++)
42     {
43         cout << a[i] << ' ';    //输出数据
44     }
45     cout << endl;
46 
47     system("pause");
48     return 0;
49 }
希尔排序

6.桶排序

桶排序,顾名思义,我们需要放置桶,对于简单的例子,可以按自然数依次放置,对于难以处理的大型数据,可以考虑“加大”桶放置的种类,使得一个区间内的都可以放进来,再对其中的各个元素进行排序。

下面给出比较简单的一种情况的思路:先找出输入数据中最大的数N,设置N+1个桶,遍历输入的数组,统计各个桶里装了多少个,最后遍历桶,得到排好序的数组。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int n, a[10001], bucket[10001], max = 0;
 9 
10     cin >> n;
11     for (int i = 0; i < n; i++)
12     {
13         cin >> a[i];    //输入数据
14     }
15 
16     for (int i = 0; i < n; i++)
17     {
18         max = (a[i] > max ? a[i] : max);    //找到最大的元素
19     }
20 
21     for (int i = 0; i < n; i++)
22     {
23         bucket[a[i]]++;     //统计各个桶的情况
24     }
25 
26     for (int i = 1; i <= max; i++)
27     {
28         if (bucket[i] == 0)
29             continue;
30         else
31         {
32             for (int j = 0; j < bucket[i]; j++)
33                 cout << i << ' ';   //输出最后的数列
34         }
35         
36     }
37     cout << endl;
38 
39     system("pause");
40     return 0;
41 }
桶排序

 

以上便是6种常见的排序方法。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM