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