三大基礎排序(氣泡排序,選擇排序,插入排序)思想
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