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

數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解

這篇具有很好參考價值的文章主要介紹了數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解,數(shù)據(jù)結(jié)構(gòu),算法,排序算法,筆記,c語言,開發(fā)語言
都說貪小便宜吃大虧,但吃虧是福,那不就是貪小便宜吃大福了嗎

一、并歸排序 MergeSort

1.基本思想

2.實現(xiàn)原理

3.代碼實現(xiàn)

4.歸并排序的特性總結(jié)

二、非遞歸并歸排序?qū)崿F(xiàn)

三、完結(jié)撒?

–?–?–?–?–?–?–?–?–?–?–?–?–?–?–?-正文開始-?–?–?–?–?–?–?–?–?–?–?–?–?–?–?–

一、并歸排序 MergeSort

1.基本思想

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

數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解,數(shù)據(jù)結(jié)構(gòu),算法,排序算法,筆記,c語言,開發(fā)語言

2.實現(xiàn)原理

其實先還是運用了遞歸大事化小的原理,假設(shè)我們要對數(shù)組arr[i]進行排序,我們可以將該數(shù)組均分為兩個數(shù)組(從中間劃分)arr[0] ~ arr[i/2],arr[i/2+1] ~ arr[i],要使arr數(shù)組有序可以先將arr[0] ~ arr[i/2]和arr[i/2+1] ~ arr[i]有序,而arr[0] ~ arr[i/2]和arr[i/2+1] ~ arr[i]有序之后可以從頭到尾比較兩個數(shù)組范圍內(nèi)的每一個值,按照要求所排的順序往新開辟的另一個數(shù)組tmp中拷貝,最后再從tmp數(shù)組中拷貝到arr數(shù)組中完成排序,這就是歸并過程。

而要想arr[0] ~ arr[i/2]和arr[i/2+1] ~ arr[i]有序,可以先讓arr[0] ~ arr[i/4]和arr[i/4+1]~arr[i/2]有序,arr[i/2+1] ~ arr[mini](中間位置)和arr[mini+1] ~ arr[i]有序,而arr[0] ~ arr[i/4]有序就需要…

這樣就可以用遞歸來實現(xiàn),數(shù)組一直向下遞歸“分割”,當(dāng)數(shù)組被分為一個數(shù)據(jù)的時候就可以返回進行合并

所以把并軌排序遞歸實現(xiàn)按照二叉樹來看,完成排序的核心要求就是遞歸“分割”后,要實現(xiàn)上層數(shù)組有序就先要實先下層數(shù)組也為有序,完成最后一層數(shù)據(jù)有序向上回溯即可完成整個數(shù)組有序

返回合并過程動態(tài)圖解:
數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解,數(shù)據(jù)結(jié)構(gòu),算法,排序算法,筆記,c語言,開發(fā)語言

3.代碼實現(xiàn)

void _MergeSort(int* a, int begin, int end, int* tmp)
{
	if (begin == end)
	{
		return;
	}

	int min = (end + begin) / 2;

	_MergeSort(a, begin, min, tmp);
	_MergeSort(a, min+1, end, tmp);

	//并歸
	int begin1 = begin, end1 = min;
	int begin2 = min + 1, end2 = end;
	int i = begin;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] <= a[begin2])
		{
			tmp[i++] = a[begin1++];
		}

		else
		{
			tmp[i++] = a[begin2++];
		}
	}

	while (begin1 <= end1)
	{
		tmp[i++] = a[begin1++];
	}

	while (begin2 <= end2)
	{
		tmp[i++] = a[begin2++];
	}

	memcpy(a+begin, tmp+begin, sizeof(int)*(end - begin + 1));//注意
}

//并歸排序 O(N*logN)
void MergeSort(int* a, int n)
{
	assert(a);

	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail");
		return;
	}

	_MergeSort(a, 0, n - 1, tmp);

	free(tmp);
	tmp = NULL;
}

4.歸并排序的特性總結(jié)

1. 歸并的缺點在于需要O(N)的空間復(fù)雜度,歸并排序的思考更多的是解決在磁盤中的外排序問題。

2. 時間復(fù)雜度:O(N*logN)

數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解,數(shù)據(jù)結(jié)構(gòu),算法,排序算法,筆記,c語言,開發(fā)語言

3. 空間復(fù)雜度:O(N)

4. 穩(wěn)定性:穩(wěn)定

二、非遞歸并歸排序?qū)崿F(xiàn)

對于歸并的非遞歸實現(xiàn)我們直接利用循環(huán)就可以解決。

我們可以將要并歸排序的數(shù)組直接看成1個數(shù)據(jù)為一組往下進行并歸,并歸后再兩個數(shù)據(jù)為一組往下進行并歸,直到將數(shù)組并歸完成為止,見下圖:

數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解,數(shù)據(jù)結(jié)構(gòu),算法,排序算法,筆記,c語言,開發(fā)語言
此過程與遞歸過程中的回溯過程一樣,只是不再需要進行遞歸分解

這個看起來容易,但實現(xiàn)起來并不簡單,我們需要注意許多細節(jié)在這里

如何通過一次循環(huán)來完成一層數(shù)據(jù)的并歸呢?

以第一層一個數(shù)據(jù)為一組為例,我們先要完成對數(shù)據(jù)的控制,開始我們就先要控制10,6一起進行并歸,而后再控制7,1進行并歸,直到第一層結(jié)束為止

完成上述代碼實現(xiàn)之后,我們只需在上述代碼外再套一層循環(huán)來控制gap,即可實現(xiàn)整個代碼邏輯

但需要注意的是并不是所有數(shù)據(jù)最終都會“組隊成雙”實現(xiàn)歸并,如下:

數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解,數(shù)據(jù)結(jié)構(gòu),算法,排序算法,筆記,c語言,開發(fā)語言
上面數(shù)組中最后一組便是一個例子

我們把每次組隊并歸的兩組中,第一組的隊頭為begin1,隊尾為end1,第二組的隊頭為begin2,隊尾為end2
因為begin1不可能越界,那么出現(xiàn)上面問題一共有三種情況:

1.end1越界

當(dāng)end1越界的話,那么表示這次組隊肯定是沒有第二組,并且第一組也部分越界,而第一組如果是一個數(shù)據(jù)的好不用進行并歸排序,如果超過一個數(shù)據(jù)說明在之前已經(jīng)并歸排序完畢,數(shù)據(jù)也是有序的,所以也不再需要進行并歸排序。end1越界直接跳出循環(huán)不進行并歸排序即可。

2.begin2越界

當(dāng)begin2越界,情況其實與end1越界一樣,不同的可能就是第一組數(shù)據(jù)都沒有越界,沒有第二組數(shù)據(jù),這時也不需要進行并歸排序,直接跳出循環(huán)即可。

3.end2越界

當(dāng)end2越界,表明有第一組數(shù)據(jù),第二組數(shù)據(jù)越界,此時只要將第二組數(shù)據(jù)的范圍縮小到原數(shù)組的隊尾即可,也就是end2 = n - 1,然后再將兩組數(shù)據(jù)進行并歸排序即可(并歸排序的實現(xiàn)只要求所給的兩組數(shù)據(jù)有序,不要求數(shù)據(jù)數(shù)量是否相等)。

代碼實現(xiàn):

//并歸排序非遞歸
void MergeSortNonR(int* a, int n)
{
	assert(a);

	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail");
		return;
	}

	int gap = 1;

	while (gap < n)
	{
		for (int j = 0; j < n; j+=gap*2)
		{
			int begin1 = j, end1 = begin1 + gap - 1;
			int begin2 = begin1 + gap, end2 = begin2 + gap - 1;

			if (end1 >= n || begin2 >= n)
			{
				break;
			}

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

			int i = j;

			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] <= a[begin2])
				{
					tmp[i++] = a[begin1++];
				}

				else
				{
					tmp[i++] = a[begin2++];
				}
			}

			while (begin1 <= end1)
			{
				tmp[i++] = a[begin1++];
			}

			while (begin2 <= end2)
			{
				tmp[i++] = a[begin2++];
			}

			memcpy(a + j, tmp + j, sizeof(int) * (end2 - j + 1));
		}
		gap *= 2;
	}

	free(tmp);
	tmp = NULL;
}

三、完結(jié)撒?

如果以上內(nèi)容對你有幫助不妨點贊支持一下,以后還會分享更多編程知識,我們一起進步。
最后我想講的是,據(jù)說點贊的都能找到漂亮女朋友?
數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解,數(shù)據(jù)結(jié)構(gòu),算法,排序算法,筆記,c語言,開發(fā)語言文章來源地址http://www.zghlxwxcb.cn/news/detail-844823.html

到了這里,關(guān)于數(shù)據(jù)結(jié)構(gòu)進階篇 之 【并歸排序】(遞歸與非遞歸實現(xiàn))詳細講解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包