C++實(shí)現(xiàn)自頂向下的歸并排序算法
本文實(shí)例講述了C++實(shí)現(xiàn)自頂向下的歸并排序算法。分享給大家供大家參考,具體如下:
一. 算法描述
自頂向下的歸并排序:采用分治法進(jìn)行自頂向下的程序設(shè)計(jì)方式,分治法的核心思想就是分解、求解、合并。
1. 先將長(zhǎng)度為N的無(wú)序序列分割平均分割為兩段
2. 然后分別對(duì)前半段進(jìn)行歸并排序、后半段進(jìn)行歸并排序
3. 最后再將排序好的前半段和后半段歸并
過程(2)中進(jìn)行遞歸求解,最終下圖詳細(xì)的分解了自頂向下的合并算法的實(shí)現(xiàn)過程:

二. 算法實(shí)現(xiàn)
/*=============================================================================
#
# FileName: mergeSort.c
# Algorithm: 歸并排序(自頂向下)
# Author: Knife
# Created: 2014-06-14 16:40:02
#
=============================================================================*/
#include<stdio.h>
#include<stdlib.h>
void merge_sort(int* intArr, int intArr_len);
void merge_array(int* intArr1, int len1, int* intArr2, int len2);
void main(){
int intArr[] = {8,3,6,4,2,9,5,4,1,7};
int n = sizeof (intArr) / sizeof (intArr[0]);
int i = 0;
merge_sort(intArr, n);
for(;i<n;i++){
printf("%d ",intArr[i]);
}
printf("\n");
}
//歸并排序(自頂向下)
void merge_sort(int* intArr, int intArr_len){
if(intArr_len > 1){
int* intArr1 = intArr;
int intArr1_len = intArr_len/2;
int* intArr2 = intArr + intArr_len/2;
int intArr2_len = intArr_len - intArr1_len;
//分別歸并排序
merge_sort(intArr1,intArr1_len);
merge_sort(intArr2,intArr2_len);
//排序
merge_array(intArr1, intArr1_len, intArr2, intArr2_len);
}
}
//合并兩個(gè)數(shù)組,并排序
void merge_array(int* intArr1, int len1, int* intArr2, int len2){
//申請(qǐng)分配空間
int* list = (int*) malloc((len1+len2) * sizeof (int));
int i = 0, j = 0, k = 0;
while(i < len1 && j < len2){
// 把較小的那個(gè)數(shù)據(jù)放到結(jié)果數(shù)組里, 同時(shí)移動(dòng)指針
list[k++] = (intArr1[i] < intArr2[j]) ? intArr1[i++] : intArr2[j++];
}
// 如果 intArr1 還有元素,把剩下的數(shù)據(jù)直接放到結(jié)果數(shù)組
while(i < len1){
list[k++] = intArr1[i++];
}
// 如果 intArr2 還有元素,把剩下的數(shù)據(jù)直接放到結(jié)果數(shù)組
while(j < len2){
list[k++] = intArr2[j++];
}
// 把結(jié)果數(shù)組 copy 到 intArr1 里
for(i = 0; i < k; i++){
intArr1[i] = list[i];
}
//釋放申請(qǐng)的空間
free(list);
}
三. 算法分析
平均時(shí)間復(fù)雜度:O(nlog2n)
空間復(fù)雜度:O(n) (用于存儲(chǔ)有序子序列合并后有序序列)
穩(wěn)定性:穩(wěn)定
希望本文所述對(duì)大家C++程序設(shè)計(jì)有所幫助。
相關(guān)文章
opencv3/C++實(shí)現(xiàn)光流點(diǎn)追蹤
今天小編就為大家分享一篇opencv3/C++實(shí)現(xiàn)光流點(diǎn)追蹤,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2019-12-12
C++?Qt實(shí)現(xiàn)動(dòng)態(tài)增加垂直滾動(dòng)條
本博文源于筆者正在工作的一個(gè)小內(nèi)容,內(nèi)容涉及到為qt動(dòng)態(tài)增加垂直滾動(dòng)條,文章分為三個(gè)部分,問題起源,問題解決方案,問題解決成功效果,思路清晰,文章干貨滿滿,復(fù)制源碼即可使用,需要的朋友可以參考下2023-08-08
C/C++通過IP獲取局域網(wǎng)網(wǎng)卡MAC地址
這篇文章主要為大家詳細(xì)介紹了C++如何通過Win32API函數(shù)SendARP從IP地址獲取局域網(wǎng)內(nèi)網(wǎng)卡的MAC地址,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02
C語(yǔ)言 鏈?zhǔn)蕉鏄浣Y(jié)構(gòu)詳解原理
二叉樹的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)是指,用鏈表來(lái)表示一棵二叉樹,即用鏈來(lái)指示元素的邏輯關(guān)系。通常的方法是鏈表中每個(gè)結(jié)點(diǎn)由三個(gè)域組成,數(shù)據(jù)域和左右指針域,左右指針分別用來(lái)給出該結(jié)點(diǎn)左孩子和右孩子所在的鏈結(jié)點(diǎn)的存儲(chǔ)地址2021-11-11
C語(yǔ)言線程池的常見實(shí)現(xiàn)方式詳解
本文介紹了如何使用 C 語(yǔ)言實(shí)現(xiàn)一個(gè)基本的線程池,線程池的實(shí)現(xiàn)包括工作線程、任務(wù)隊(duì)列、任務(wù)調(diào)度、線程池的初始化、任務(wù)添加、銷毀等步驟,感興趣的朋友跟隨小編一起看看吧2025-01-01
C語(yǔ)言 90后懷舊游戲超級(jí)瑪麗的實(shí)現(xiàn)流程
90后最風(fēng)靡的游戲是什么?第一個(gè)聯(lián)想到的肯定是插卡游戲機(jī)或者VCD加光盤運(yùn)行在電視機(jī)上的超級(jí)瑪麗了,它的經(jīng)典絕對(duì)可以排在第一位,長(zhǎng)大后的我們今天來(lái)用C語(yǔ)言重溫一下2021-11-11

