国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【排序算法】 歸并排序詳解!分治思想!

這篇具有很好參考價(jià)值的文章主要介紹了【排序算法】 歸并排序詳解!分治思想!。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【排序算法】 歸并排序詳解!分治思想!,算法的奇妙之旅,算法,排序算法,數(shù)據(jù)結(jié)構(gòu)

?? 嶼小夏 : 個(gè)人主頁
??個(gè)人專欄 : 算法—排序篇
?? 莫道桑榆晚,為霞尚滿天!

??前言

? 什么是歸并?通過歸并排序就能讓數(shù)據(jù)有序?分治法是怎么在歸并排序上應(yīng)用的?本文將對歸并排序進(jìn)行細(xì)致入微的講解,庖丁解牛般讓你徹底明白歸并排序!

???歸并排序的思想

??基本思想

歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide andConquer)的一個(gè)非常典型的應(yīng)用。
將已有序的子序列合并,得到完全有序的序列;即先使每個(gè)子序列有序,再使子序列段間有序。若將兩個(gè)有序表合并成一個(gè)有序表,稱為二路歸并。

??歸并的思想實(shí)現(xiàn)

? 將兩個(gè)有序數(shù)組合并成一個(gè)有序數(shù)組的操作。在歸并排序中,通過不斷地將數(shù)組分成兩半,分別對每一半進(jìn)行排序,然后將排好序的兩個(gè)子數(shù)組合并成一個(gè)有序數(shù)組,最終得到整個(gè)數(shù)組有序的結(jié)果。

??分治法

? 分治法在歸并排序中的應(yīng)用是將問題分解成更小的子問題,然后分別解決這些子問題,最后將子問題的解合并起來得到原問題的解。具體來說,歸并排序的分治法應(yīng)用如下:

  1. 分解:將待排序的數(shù)組分成兩個(gè)子數(shù)組,分別為左子數(shù)組和右子數(shù)組。
  2. 解決:遞歸地對左子數(shù)組和右子數(shù)組進(jìn)行歸并排序。
  3. 合并:將排好序的左子數(shù)組和右子數(shù)組合并成一個(gè)有序數(shù)組。

???歸并排序的實(shí)現(xiàn)

??核心操作步驟

靜圖全步驟概覽:

【排序算法】 歸并排序詳解!分治思想!,算法的奇妙之旅,算法,排序算法,數(shù)據(jù)結(jié)構(gòu)

動(dòng)圖一步步的邏輯實(shí)現(xiàn):

【排序算法】 歸并排序詳解!分治思想!,算法的奇妙之旅,算法,排序算法,數(shù)據(jù)結(jié)構(gòu)

??遞歸版歸并實(shí)現(xiàn)

//歸并
void _MergeSort(int* a, int* tmp, int begin, int end)
{
	if (end <= begin)
	{
		return;
	}
	int mid = (begin + end) / 2;
	_MergeSort(a, tmp, begin, mid);
	_MergeSort(a, tmp, mid + 1, end);
	// a->[begin, mid][mid+1, end]->tmp
	//歸并
	int begin1 = begin, end1 = mid;
	int begin2 = mid + 1, end2 = end;
	int index = begin;

	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] <= a[begin2])
		{
			tmp[index++] = a[begin1++];
		}
		else
		{
			tmp[index++] = a[begin2++];
		}
	}
	while (begin1 <= end1)
	{
		tmp[index++] = a[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[index++] = a[begin2++];
	}
	memcpy(a + begin, tmp + begin, (end - begin + 1) * sizeof(int));
}
//歸并(遞歸版)
void MergeSort(int* a, int n)
{
	int* tmp = malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	_MergeSort(a, tmp, 0, n - 1);
	free(tmp);
}

? 歸并需要開一個(gè)同樣大的tmp數(shù)組來存放數(shù)據(jù),相當(dāng)于是拿空間來換時(shí)間了.

?代碼實(shí)現(xiàn)詳解:

  1. 首先,將整個(gè)序列分為兩部分,分別遞歸調(diào)用_MergeSort函數(shù)對左右兩部分進(jìn)行排序。
  2. 在_MergeSort函數(shù)中,首先判斷遞歸終止條件,如果end小于等于begin,則表示當(dāng)前子序列只有一個(gè)元素或者為空,無需排序,直接返回。
  3. 然后,計(jì)算中間位置mid,并分別遞歸調(diào)用_MergeSort函數(shù)對左右兩部分進(jìn)行排序。
  4. 接下來,進(jìn)行歸并操作。首先,設(shè)置四個(gè)指針begin1、end1、begin2、end2分別指向左右兩部分的起始和結(jié)束位置,以及一個(gè)指針index指向當(dāng)前歸并結(jié)果的位置。
  5. 然后,使用兩個(gè)循環(huán)比較左右兩部分的元素大小,并將較小的元素放入tmp數(shù)組中,同時(shí)移動(dòng)相應(yīng)的指針。
  6. 最后,將剩余的元素復(fù)制到tmp數(shù)組中。
  7. 最后,將tmp數(shù)組中的元素復(fù)制回原數(shù)組a中,完成歸并排序。

??非遞歸版歸并實(shí)現(xiàn)

? 非遞歸版是在遞歸上進(jìn)行了修改,將其遞歸改為了循環(huán)。

//歸并(非遞歸版)
void _MergeSortNotR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	int gap = 1;
	while (gap < n)
	{
		for (int i = 0; i < n; i += 2 * gap)
		{
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;

			if (begin2 >= n)
			{
				break;
			}
			if (end2 >= n)
			{
				end2 = n - 1;
			}

			int index = i;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] <= a[begin2])
				{
					tmp[index++] = a[begin1++];
				}
				else
				{
					tmp[index++] = a[begin2++];
				}
			}
			while (begin1 <= end1)
			{
				tmp[index++] = a[begin1++];
			}
			while (begin2 <= end2)
			{
				tmp[index++] = a[begin2++];
			}
			memcpy(a+i, tmp+i, (end2-i+1) * sizeof(int));
		}
		gap *= 2;
	}
	free(tmp);
}

?代碼實(shí)現(xiàn)詳解:

  1. 分配一個(gè)臨時(shí)數(shù)組tmp,用于存儲(chǔ)歸并結(jié)果。

  2. 設(shè)置一個(gè)變量gap為1,表示歸并的間隔大小。

  3. 接下來,循環(huán)執(zhí)行以下操作,直到gap大于等于n:

    1. 遍歷整個(gè)數(shù)組,每次取兩個(gè)相鄰的子序列進(jìn)行歸并。
    2. 計(jì)算左右兩個(gè)子序列的起始和結(jié)束位置。
    3. 判斷右子序列的結(jié)束位置是否超過了數(shù)組的長度,如果超過,則將結(jié)束位置設(shè)置為數(shù)組的最后一個(gè)元素的下標(biāo)。
    4. 使用兩個(gè)指針begin1和begin2分別指向左右兩個(gè)子序列的起始位置,使用指針end1和end2分別指向左右兩個(gè)子序列的結(jié)束位置。
    5. 使用一個(gè)指針index指向當(dāng)前歸并結(jié)果的位置。
    6. 使用一個(gè)循環(huán),比較左右兩個(gè)子序列的元素大小,并將較小的元素放入臨時(shí)數(shù)組tmp中,同時(shí)移動(dòng)相應(yīng)的指針。
    7. 如果左子序列還有剩余元素,則將剩余元素復(fù)制到tmp數(shù)組中。
    8. 如果右子序列還有剩余元素,則將剩余元素復(fù)制到tmp數(shù)組中。
    9. 將tmp數(shù)組中的元素復(fù)制回原數(shù)組a中。
    10. 將gap乘以2,進(jìn)行下一輪歸并。
  4. 最后,釋放臨時(shí)數(shù)組tmp的內(nèi)存空間。

???歸并排序特性總結(jié)

  1. 穩(wěn)定性:歸并排序是一種穩(wěn)定的排序算法,即相等元素的相對順序在排序后不會(huì)改變。
  2. 時(shí)間復(fù)雜度:歸并排序的時(shí)間復(fù)雜度是O(nlogn),其中n是待排序序列的長度。這是由于歸并排序的核心操作是將序列分成兩個(gè)子序列,然后分別進(jìn)行排序,再將排序好的子序列合并,而分割和合并操作都需要O(logn)的時(shí)間,所以總的時(shí)間復(fù)雜度是O(nlogn)。
  3. 空間復(fù)雜度:歸并排序的空間復(fù)雜度是O(n),其中n是待排序序列的長度。這是由于歸并排序需要一個(gè)與待排序序列相同大小的額外空間來存儲(chǔ)臨時(shí)的合并結(jié)果。
  4. 非原地排序:歸并排序不是原地排序算法,即它需要額外的空間來存儲(chǔ)臨時(shí)的合并結(jié)果。這是因?yàn)樵诤喜⒉僮髦?,需要同時(shí)訪問兩個(gè)子序列的元素,并將它們按照順序合并到一個(gè)新的序列中。
  5. 遞歸實(shí)現(xiàn):歸并排序通常使用遞歸的方式來實(shí)現(xiàn),即將待排序序列不斷分割成更小的子序列,直到子序列的長度為1,然后再將這些子序列按照順序合并成一個(gè)有序的序列。遞歸實(shí)現(xiàn)的歸并排序代碼簡潔易懂,但是由于遞歸調(diào)用的開銷比較大,所以在實(shí)際應(yīng)用中可能會(huì)使用迭代的方式來實(shí)現(xiàn)歸并排序。
  6. 適用性:歸并排序適用于各種數(shù)據(jù)規(guī)模的排序,而且對于大規(guī)模數(shù)據(jù)的排序效果較好。它的時(shí)間復(fù)雜度穩(wěn)定在O(nlogn),不會(huì)因?yàn)閿?shù)據(jù)規(guī)模的增大而導(dǎo)致時(shí)間復(fù)雜度的增加。此外,歸并排序還適用于外部排序,即對于無法一次性加載到內(nèi)存的大規(guī)模數(shù)據(jù)進(jìn)行排序。

???全篇總結(jié)

? 經(jīng)過對歸并排序的思想,特性,代碼實(shí)現(xiàn)這些細(xì)致入微的講解,相信聰明的你肯定已經(jīng)學(xué)會(huì)了叭????!

?? 好了,由于篇幅有限,本章只是對歸并進(jìn)行了深度解刨,后序會(huì)出更多的排序算法哦!
看到這里希望給博主留個(gè):??點(diǎn)贊??收藏??關(guān)注!
你們的點(diǎn)贊就是博主更新最大的動(dòng)力!
有問題可以評論或者私信呢秒回哦!
【排序算法】 歸并排序詳解!分治思想!,算法的奇妙之旅,算法,排序算法,數(shù)據(jù)結(jié)構(gòu)文章來源地址http://www.zghlxwxcb.cn/news/detail-715470.html

到了這里,關(guān)于【排序算法】 歸并排序詳解!分治思想!的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 考研算法31天:歸并排序 【歸并排序,分治】

    考研算法31天:歸并排序 【歸并排序,分治】

    算法介紹 歸并算法其過程分為三步: 1.分:遞歸到最下面 2.治:兩個(gè)元素之間排序。 3。歸:遞歸到最下層然后返回,從兩個(gè)元素變成四個(gè)元素再排序。 如下圖所示: 動(dòng)態(tài)圖如下: 算法題目 算法ac代碼:

    2024年02月11日
    瀏覽(22)
  • 算法基礎(chǔ)15 —— 分治算法(歸并排序 + 快速排序)

    算法基礎(chǔ)15 —— 分治算法(歸并排序 + 快速排序)

    分治法的基本概念、思想 分治法是一種很重要的算法。 字面解釋,分治分治,分而治之。就是把一個(gè)復(fù)雜的問題分成兩個(gè)或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最后子問題可以簡單的直接求解,原問題的解即子問題的解的合并。 不難發(fā)現(xiàn),分

    2024年02月03日
    瀏覽(22)
  • 歸并算法:分治而治的高效算法大揭秘(圖文詳解)

    歸并算法:分治而治的高效算法大揭秘(圖文詳解)

    ?? 鴿芷咕 :個(gè)人主頁 ??? 個(gè)人專欄 : 《數(shù)據(jù)結(jié)構(gòu)算法》《粉絲福利》 ??生活的理想,就是為了理想的生活! 歸并算法是我們算法中最常見的算法之一,其思想非常巧妙。本身歸并是只能歸并有序數(shù)組但是當(dāng)我們利用了二路歸并分治法之后,就可以使用歸并的思想來幫我

    2024年02月03日
    瀏覽(21)
  • 數(shù)據(jù)結(jié)構(gòu)——排序算法——?dú)w并排序

    數(shù)據(jù)結(jié)構(gòu)——排序算法——?dú)w并排序

    在第二個(gè)列表向第一個(gè)列表逐個(gè)插入的過程中,由于第二個(gè)列表已經(jīng)有序,所以后續(xù)插入的元素一定不會(huì)在前面插入的元素之前。在逐個(gè)插入的過程中,每次插入時(shí),只需要從上次插入的位置開始,繼續(xù)向后尋找插入位置即可。這樣一來,我們最多只需要將兩個(gè)有序數(shù)組遍歷

    2024年02月09日
    瀏覽(34)
  • 數(shù)據(jù)結(jié)構(gòu)和算法筆記4:排序算法-歸并排序

    數(shù)據(jù)結(jié)構(gòu)和算法筆記4:排序算法-歸并排序

    歸并排序算法完全遵循分治模式。直觀上其操作如下: 分解:分解待排序的n個(gè)元素的序列成各具n/2個(gè)元素的兩個(gè)子序列。 解決:使用歸并排序遞歸地排序兩個(gè)子序列。 合并:合并兩個(gè)已排序的子序列以產(chǎn)生已排序的答案。 我們直接來看例子理解算法的過程,下面是要排序

    2024年01月21日
    瀏覽(36)
  • 數(shù)據(jù)結(jié)構(gòu)與算法—?dú)w并排序&計(jì)數(shù)排序

    數(shù)據(jù)結(jié)構(gòu)與算法—?dú)w并排序&計(jì)數(shù)排序

    目錄 一、歸并排序 1、主函數(shù) 2、遞歸實(shí)現(xiàn) 3、優(yōu)化遞歸? 4、非遞歸實(shí)現(xiàn) 5、特性總結(jié): 二、計(jì)數(shù)排序 1、代碼: 2、特性總結(jié): 三、各種排序總結(jié) 時(shí)間空間復(fù)雜度匯總? 基本思想: 歸并排序是建立在歸并操作上的一種有效的排序算法,該算法是采用 分治法 的一個(gè)非常典型的

    2024年02月04日
    瀏覽(30)
  • 數(shù)據(jù)結(jié)構(gòu)算法--5 歸并排序

    數(shù)據(jù)結(jié)構(gòu)算法--5 歸并排序

    我們先看一下歸并排序是怎么歸并的 ?兩個(gè)有序列表,有l(wèi)ow指針指向2,high指針指向6,mid指針指向9 再建一個(gè)新列表,12,所以1放到列表,右指針右移一位,再比較2和3,2放入列表,左指針右移一位,以此類推,肯定有一部分列表率先沒有數(shù),這時(shí)將另一列表直接append進(jìn)入新

    2024年02月11日
    瀏覽(29)
  • 數(shù)據(jù)結(jié)構(gòu)與算法:歸并排序

    數(shù)據(jù)結(jié)構(gòu)與算法:歸并排序

    在講解歸并排序前,我們先看到一個(gè)問題: 對于這樣兩個(gè)有序的數(shù)組,如何將它們合并為一個(gè)有序的數(shù)組? 在此我們處理這個(gè)問題的思路就是:開辟一個(gè)新的數(shù)組,然后分別安置一個(gè)指針在左右數(shù)組,利用指針遍歷數(shù)組,每次對比將比較小的那個(gè)元素插入到數(shù)組的尾部。 像

    2024年01月21日
    瀏覽(34)
  • 【數(shù)據(jù)結(jié)構(gòu)】排序算法(二)—>冒泡排序、快速排序、歸并排序、計(jì)數(shù)排序

    【數(shù)據(jù)結(jié)構(gòu)】排序算法(二)—>冒泡排序、快速排序、歸并排序、計(jì)數(shù)排序

    ?? 樊梓慕: 個(gè)人主頁 ??? 個(gè)人專欄: 《C語言》《數(shù)據(jù)結(jié)構(gòu)》《藍(lán)橋杯試題》《LeetCode刷題筆記》《實(shí)訓(xùn)項(xiàng)目》 ?? 每一個(gè)不曾起舞的日子,都是對生命的辜負(fù) 目錄 前言 1.冒泡排序 2.快速排序 2.1Hoare版 2.2占坑版 2.3前后指針版 2.4三數(shù)取中對快速排序的優(yōu)化 2.5非遞歸版 3.歸

    2024年02月08日
    瀏覽(34)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包