舉例講解C語(yǔ)言對(duì)歸并排序算法的基礎(chǔ)使用
基礎(chǔ)概念
百度百科是這么描述歸并排序的:
歸并操作(merge),也叫歸并算法,指的是將兩個(gè)已經(jīng)排序的序列合并成一個(gè)序列的操作。
設(shè)有數(shù)列
{6,202,100,301,38,8,1}
初始狀態(tài):
[6] [202] [100] [301] [38] [8] [1]
比較次數(shù)
i=1 [6 202 ] [ 100 301] [ 8 38] [ 1 ] 3 i=2 [ 6 100 202 301 ] [ 1 8 38 ] 4 i=3 [ 1 6 8 38 100 202 301 ] 4
總計(jì): 11次
實(shí)例
#include <stdio.h>
void printArr(int arr[],int length){
int i;
for(i=0;i<length;i++){
printf("%d,",arr[i]);
}
printf("\n");
}
void merge(int a[],int alength,int b[],int blength,int c[]){//將2個(gè)已排好序的數(shù)組合并到數(shù)組c
int i=0,j=0,k=0;
while(1){
if(a[i]<=b[j]){
c[k] = a[i];
i++;
k++;
if(i==alength){
for(;j<blength;j++,k++){
c[k] = b[j];
}
break;
}
}else{
c[k] = b[j];
j++;
k++;
if(j==blength){
for(;i<alength;i++,k++){
c[k] = a[i];
}
break;
}
}
}
printArr(c,k);
}
void mergeSort(int arr[],int length){//將一個(gè)數(shù)組分成2個(gè)數(shù)組,前l(fā)ength-1為第一個(gè),最后一個(gè)為第二個(gè),然后合并2個(gè)數(shù)組
if(length > 1){
int arr1[length-1],arr2[1] = {arr[length-1]};
int i;
for(i=0;i<length-1;i++){
arr1[i] = arr[i];
}
mergeSort(arr1,length-1);//遞歸的調(diào)用自己
merge(arr1,length-1,arr2,1,arr);
}
}
int main(void){
int a[10] = {3,54,16,8,123,8,89,23,87,2};
printArr(a,10);
mergeSort(a,10);
return 0;
}
算法性能/復(fù)雜度
歸并排序的效率是很高的,由于遞歸劃分為子序列只需要logN復(fù)雜度,而合并每?jī)蓚€(gè)子序列需要大約2n次賦值,為O(n)復(fù)雜度,因此,只需要簡(jiǎn)單相乘即可得到歸并排序的時(shí)間復(fù)雜度 O(㏒n)。并且由于歸并算法是固定的,不受輸入數(shù)據(jù)影響,所以它在最好、最壞、平均情況下表現(xiàn)幾乎相同,均為O(㏒n)。
但是,歸并排序最大的缺陷在于其空間復(fù)雜度。從上面的代碼可以看到,在合并子數(shù)組的時(shí)候需要一個(gè)輔助數(shù)組,然后再把這個(gè)數(shù)據(jù)拷貝回原數(shù)組。所以,歸并排序的空間復(fù)雜度(額外空間)為O(n)??刹豢梢允÷赃@個(gè)數(shù)組呢?不行!如果取消輔助數(shù)組而又要保證原來(lái)的數(shù)組中數(shù)據(jù)不被覆蓋,那就必須要在數(shù)組中花費(fèi)大量時(shí)間來(lái)移動(dòng)數(shù)據(jù)。不僅容易出錯(cuò),還降低了效率。因此這個(gè)輔助空間是少不掉的。
算法穩(wěn)定性
因?yàn)槲覀冊(cè)谟龅较嗟鹊臄?shù)據(jù)的時(shí)候必然是按順序“抄寫(xiě)”到輔助數(shù)組上的,所以,歸并排序同樣是穩(wěn)定算法。
算法適用場(chǎng)景
歸并排序在數(shù)據(jù)量比較大的時(shí)候也有較為出色的表現(xiàn)(效率上),但是,其空間復(fù)雜度O(n)使得在數(shù)據(jù)量特別大的時(shí)候(例如,1千萬(wàn)數(shù)據(jù))幾乎不可接受。而且,考慮到有的機(jī)器內(nèi)存本身就比較小,因此,采用歸并排序一定要注意。
相關(guān)文章
C++設(shè)計(jì)模式之策略模式(Strategy)
這篇文章主要為大家詳細(xì)介紹了C++設(shè)計(jì)模式之策略模式Strategy ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
Visual Studio 2019安裝使用C語(yǔ)言程序(VS2019 C語(yǔ)言)
這篇文章主要介紹了Visual Studio 2019安裝使用C語(yǔ)言程序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
VS C++頭文件引用提示“未定義標(biāo)識(shí)符”的問(wèn)題解決
本文主要介紹了VS C++頭文件引用提示“未定義標(biāo)識(shí)符”的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
使用C++構(gòu)建一個(gè)優(yōu)先級(jí)隊(duì)列的實(shí)現(xiàn)
優(yōu)先級(jí)隊(duì)列是一種特殊的隊(duì)列數(shù)據(jù)結(jié)構(gòu),本文主要介紹了使用C++構(gòu)建一個(gè)優(yōu)先級(jí)隊(duì)列的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02
C語(yǔ)言一個(gè)函數(shù)如何實(shí)現(xiàn)好幾個(gè)return返回值
本文主要介紹了C語(yǔ)言一個(gè)函數(shù)如何實(shí)現(xiàn)好幾個(gè)return返回值,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
C語(yǔ)言實(shí)現(xiàn)串的順序存儲(chǔ)表示與基本操作
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)串的順序存儲(chǔ)表示與基本操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
C++實(shí)現(xiàn)LeetCode(73.矩陣賦零)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(73.矩陣賦零),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
c語(yǔ)言統(tǒng)計(jì)素?cái)?shù)之和的實(shí)例
這篇文章主要介紹了c語(yǔ)言統(tǒng)計(jì)素?cái)?shù)之和的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
C語(yǔ)言手把手教你實(shí)現(xiàn)貪吃蛇AI(下)
這篇文章主要手把手教你實(shí)現(xiàn)C語(yǔ)言版貪吃蛇AI,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01

