1. 程式人生 > >三大基礎排序(氣泡排序,選擇排序,插入排序)思想

三大基礎排序(氣泡排序,選擇排序,插入排序)思想

1.氣泡排序


1-1 思想:

氣泡排序思想:從陣列的下標為0的元素開始,首先將下標為0的下標與陣列下標為1的元素比較,如果陣列下標1
的元素更小,交換,接著比較下標1與下標2的元素,如果下標2較小則交換,反之接著將下標2與下標3比較。。。
以此類推,經過n-1趟排序就可以得到結果 。
比如5,4,3,2,1
第一趟:5,4比較交換。交換後:4,5,3,2,1
5,3比較交換。交換後:4,3,5,2,1
5,2比較交換。交換後:4,3,2,5,1
5,1比較交換。交換後:4,3,2,1,5
剩下的以此類推
如果是五個數只要四趟迴圈就可以排好,n個數據只要(n-1)趟排序
每一趟排序需要比較的次數,五個數的話第一趟比較4次
第二趟比較3次,因為第一趟已經把最大的元素找到了
所以只要在剩下4個元素中比較3次即可
剩下的以此類推。
時間複雜度:O(N^2) 。


1-2原始碼:

/*
氣泡排序思想:從陣列的下標為0的元素開始,首先將下標為0的下標與陣列下標為1的元素比較,如果陣列下標1
的元素更小,交換,接著比較下標1與下標2的元素,如果下標2較小則交換,反之接著將下標2與下標3比較。。。
以此類推,經過n-1趟排序就可以得到結果 
時間複雜度:O(N^2) 
*/

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int nums[101];

void BubbleSort(int *a,int n)
{
    for(int i = 0;i<n;i++){
        for(int j = 0;j<n-i-1;j++){
            if(a[j]>a[j+1])
            {
                swap(a[j],a[j+1]);
            }
        }
    }
}

int main()
{
    int n;
    cout<<"input n:"<<endl;
    cin>>n;
    for(int i = 0;i<n;i++)
    cin>>nums[i];
    BubbleSort(nums,n);
    for(int i = 0;i<n;i++)
    cout<<nums[i]<<" ";
    return 0;
}

2.選擇排序


2-1思想:

選擇排序思想:每次排序將陣列中最小的元素放到未排序的第一個
如 3 2 0 5 1
先以陣列首元素為參考值,然後依次與後面的元素比較,有小的將其交換
第二步,從陣列的第二個元素為參考值,然後依次與剩下的元素比較,有小的將其交換 。
比如5,4,3,2,1
第一趟:5為參考值,然後與4比較交換,交換後:4,5,3,2,1
然後以4為參考值,與3比較交換,交換後:3,5,4,2,1
然後以3為參考值,與2比較交換,交換後:2,5,4,3,1
然後以2為參考值,與1比較交換,交換後:1,5,4,3,2
第二趟以此類推
一共進行n-1趟排序,每一趟排序進行n-i-1次排序
後面依次類推 。
時間複雜度為O(N^2) 。


2-2原始碼:

/*
選擇排序思想:每次排序將陣列中最小的元素放到未排序的第一個
如 3 2 0 5 1
先以陣列首元素為參考值,然後依次與後面的元素比較,有小的將其交換
第二步,從陣列的第二個元素為參考值,然後依次與剩下的元素比較,有小的將其交換 
後面依次類推 
時間複雜度為O(N^2) 

*/ 

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

int a[1000];

void SelectionSort(int *a,int n)
{
     for(int i = 0;i<n;i++)
     {
         for(int j = i+1;j<n;j++)
         {
             if(a[j]<a[i])
             swap(a[j],a[i]);
         }
     }
}

int main()
{
    int n;
    cout<<"input n:"<<endl;
    cin>>n;
    for(int i = 0;i<n;i++)
    cin>>a[i];
    SelectionSort(a,n);
    for(int i = 0;i<n;i++)
    cout<<a[i]<<" ";
    return 0;
}

3.插入排序


3-1思想:

插入排序思想:插入排序就是先將陣列首元素不動,從陣列的第一個開始與前一個數比較,如果小於當前元素則
交換,反之不作操作,做完這一步操作以後,我們暫且認為陣列的0,1位置排好序,然後用下標為2的元素與前一
個元素(下標1的元素)比較,如果較小則交換,進而再與下標為1的元素的前一個比較,如果較小則在交換。這
就類似於我們在0,1排好序了而需要將2對應的元素插入到原來排好序的0,1中
比如5,4,3,2,1。
第一趟排序:5與4比較交換變成4,5
第二趟排序:因為4,5排序好了,先將3與5比較交換,再將3與4比較交換。
以此類推一共需要進行n-1趟排序
以此類推
時間複雜度:與陣列的資料狀況有關係
假設是有序的1,2,3,4,5只做比較而不用交換,此時時間複雜度O(N)最好情況
假設是無序的5,4,3,2,1每次都要交換,此時時間複雜度為O(N^2)最壞情況
實際上,插入排序是O(N^2)


3-2原始碼:

/*
插入排序思想:插入排序就是先將陣列首元素不動,從陣列的第一個開始與前一個數比較,如果小於當前元素則
交換,反之不作操作,做完這一步操作以後,我們暫且認為陣列的0,1位置排好序,然後用下標為2的元素與前一
個元素(下標1的元素)比較,如果較小則交換,進而再與下標為1的元素的前一個比較,如果較小則在交換。這
就類似於我們在0,1排好序了而需要將2對應的元素插入到原來排好序的0,1中 
以此類推 
時間複雜度:與陣列的資料狀況有關係
假設是有序的1,2,3,4,5只做比較而不用交換,此時時間複雜度O(N)最好情況 
假設是無序的5,4,3,2,1每次都要交換,此時時間複雜度為O(N^2)最壞情況 
實際上,插入排序是O(N^2) 
*/

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

int a[1000];

void InsertSort(int *a,int n)
{
    for(int i = 0;i<n-1;i++)    //實際交換隻有n-2次 
    {
        for(int j = i+1;j>=0;j--)
        {
            if(a[j]<a[j-1])
            swap(a[j-1],a[j]);
        }
    }
}

int main()
{
    int n;
    cout<<"input n:"<<endl;
    cin>>n;
    for(int i = 0;i<n;i++)
    cin>>a[i];
    InsertSort(a,n);
    for(int i = 0;i<n;i++)
    cout<<a[i]<<" ";
    return 0;
}

4.總結

現在,這三大基礎演算法,冒泡與選擇已經基本不用了,因為效率低,但是插入排序還會繼續用。
因為冒泡與選擇不管陣列的資料是否有序,它都需要進行規定操作時間複雜度為O(N^2)。
而插入排序在陣列有序的情況下根本不用交換時間複雜度為O(N),還是相當可觀的。
在使用基礎演算法排序時,儘可能使用插入排序。

可以關注一下自建Blog:http://47.107.118.184