冒牌排序(BubbleSort)
冒泡排序是一種比較簡單的排序算法,它循環走過需要排序的元素,依次比較相鄰的兩個元素,如果順序錯誤就交換,直至沒有元素交換,完成排序。
若對n個人進行排序,我們需要n-1次比較,所以第k次比較需要進行n-k次比較。排序算法通過以數據對象的兩兩比較作為關鍵,所以可以得出,冒泡排序需要進行的
比較次數為:(n-1) + (n-2) + ... + 1 = n*(n-1) / 2,因此冒泡排序的時間復雜度為O(n^2)。
算法簡介:
1.比較相鄰的元素,前一個比后一個大(或者前一個比后一個小)調換位置
2.每一對相鄰的元素進行重復的工作,從開始對一直到結尾對,這步完成后,結尾為做大或最小的數.
3.針對除了最后一個元素重復進行上面的步驟。
4.重復1-3步驟直到完成排序
動畫演示:
代碼如下
#include<stdio.h>
void BuddleSort(int a[],int n){
for(int i=0;i<n-1;i++){
for( int j=0;j<n-i-1;j++){
if(a[j]>a[j+1]){
int swap=a[j];
a[j]=a[j+1];
a[j+1]=swap;
}
}
}
}
int main(){
int a[]={6, 9,8,4,5,2,1,3,7};
int n=sizeof(a)/sizeof(int);
BuddleSort(a,n);
printf("冒泡排序結果:");
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
return 0;
}
冒牌排序改進版:雞尾酒排序
雞尾酒排序:又名為定向冒泡排序,相比較於傳統的冒泡排序改進方法就是加入一個標志性變量exchange,用於標志某次排序過程中
是否由數據交換,若某一次排序沒有進行數據交換,則說明數據已經排列好,可以立刻結束排序,避免不必要的后續比較過程,從而提高性能。
算法描述:每次排序進行正向和反向冒泡一次得到兩個終值(最大值和最小值)。
代碼如下
#include<stdio.h>
void BuddleSort(int a[],int n)
{
int left=0; //設置變量初始值
int right=n-1;
int swap,j;
while(left<right){
for(j=left;j<right;j++)//正向冒泡,找出最大值
{
if(a[j]>a[j+1])
{
swap=a[j];
a[j]=a[j+1];
a[j+1]=swap;
}
}
right--; //前移一位
for(int j=right;j>left;j--)//反向冒泡找出最小值
{
if(a[j-1]>a[j])
{
swap=a[j];
a[j]=a[j-1];
a[j-1]=swap;
}
}
left++; //修改left值。后移一位
}
}
int main()
{
int a[]={7,8,4,2,9,5,6,1,3};
int n=sizeof(a)/sizeof(int);
BuddleSort(a,n);
printf("雞尾酒排序結果:");
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
選擇排序(SelectSort)
選擇排序是一種簡單直觀的排序算法,工作原理為:在未排序的序列中找出最小(大)元素與第一個位置的元素交換位置
注意選擇排序與冒泡排序的區別:冒泡排序通過依次交換相鄰兩個順序不合法的元素位置,從而將當前最小(大)元素放到合適的位置;而選擇排序每遍歷一次都記住了當前最小(大)元素的位置,最后僅需一次交換操作即可將其放到合適的位置。
然后在剩下的元素中再找最小(大)元素與第二個元素的位置交換,依此類推,直到所有元素排序排序完成。根據上述描述,一共進行n-1趟比較后,就能完成整個排隊過程。我們可以知道,第k趟比較需要進行的數組元素的兩兩比較的次數為n-k次,所以共需要的比較次數為n*(n-1) / 2,因此選擇排序算法的時間復雜度與冒泡排序一樣,也為O(n^2)。
算法簡介:
1.初始狀態:序列為無序狀態。
2.第1次排序:從n個元素中找出最小(大)元素與第1個記錄交換
3.第2次排序:從n-1個元素中找出最小(大)元素與第2個記錄交換
4.第i次排序:從n-i+1個元素中找出最小(大)元素與第i個記錄交換
5.以此類推直到排序完成
動畫演示:
代碼如下
#include<stdio.h>
void SelectSort(int a[],int n)
{
for(int i=0;i<n-1;i++)
{
int min=i; //存放數組最小值的位置
for(int j=i+1;j<n;j++)
{
if(a[j]<a[min]){
min=j; //找出最小值,並記錄位置
}
}
if(min!=i) //最小元素與第i個元素互換位置
{
int swap=a[min];
a[min]=a[i];
a[i]=swap;
}
}
}
int main()
{
int a[]={8,9,7,1,5,4,2,3,6};
int n=sizeof(a)/sizeof(int);
SelectSort(a,n);
printf("選擇排序結果:");
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
插入排序(InsertSort)
插入排序是一種簡單直觀的排序算法,工作原理為構建有序序列,對於未排序元素,在已排序序列中從后向前掃描,找到相應位置並插入。插入排序在實現上,通常采用in-place排序(即只需用到O(1)的額外空間的排序),因而在從后向前掃描過程中,需要反復把已排序元素逐步向后挪位,為最新元素提供插入空間,直到排序完成,如果碰見一個和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后順序沒有改變,從原無序序列出去的順序就是排好序后的順序,所以插入排序是穩定的。理解了插入排序的思想后,我們便能夠得到它的時間復雜度。對於n個元素,一共需要進行n-1輪比較,而第k輪比較需要進行k次數組元素的兩兩比較,因此共需要進行的比較次數為:1 + 2 + ... + (n-1),所以插入排序的時間復雜度同冒泡排序一樣,也為O(n^2)。
算法簡介:
1.從第一個元素開始,該元素可認為已排序。
2.取出下一個元素,在排序好的元素序列中從后往前掃描
3.如果元素(已排序)大於新元素,將該元素移到下一位置
4.重復3.直到找到已排序的元素小於或等於新元素的位置
5.將新元素插入該位置后
6.重復2-5直到排序完成
動畫演示:
代碼如下
#include<stdio.h>
void InsertSort(int a[],int n)
{
for(int i=0;i<n;i++)
{
int j=i-1;
if(a[i]<a[i-1]){ //若第i個元素小於第i-1個元素,移動有序序列插入------大於的話則直接插入
int swap=a[i]; //存儲將要排序的元素
a[i]=a[i-1]; //向后移動一個元素
while(swap<a[j])//查詢將要插入的位置
{
a[j+1]=a[j];
j--; //元素后移
}
a[j+1]=swap;//循環結束 插入到指定位置
}
}
}
int main() {
int a[] = { 9,7,8,2,5,1,3,6,4};
int n = sizeof(a)/sizeof(int);
InsertSort(a, n);
printf("排序好的數組為:");
for (int i = 0; i < n; i++) {
printf(" %d", a[i]);
}
printf("\n");
return 0;
}
還有幾種經典的排序算法沒有寫出,后續將補充,有不足之處還請指出。謝謝