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

【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化

這篇具有很好參考價(jià)值的文章主要介紹了【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
快速排序是Hoare于1962年提出的一種二叉樹結(jié)構(gòu)的交換排序方法,其基本思想為:任取待排序元素序列中
的某元素作為基準(zhǔn)值,按照該排序碼將待排序集合分割成兩子序列,左子序列中所有元素均小于基準(zhǔn)值,右
子序列中所有元素均大于基準(zhǔn)值,然后最左右子序列重復(fù)該過程,直到所有元素都排列在相應(yīng)位置上為止

// 假設(shè)按照升序?qū)rray數(shù)組中[left, right)區(qū)間中的元素進(jìn)行排序
void QuickSort(int array[], int left, int right)
{
 if(right - left <= 1)
 return;
 
 // 按照基準(zhǔn)值對array數(shù)組的 [left, right)區(qū)間中的元素進(jìn)行劃分
 int div = partion(array, left, right);
 
 // 劃分成功后以div為邊界形成了左右兩部分 [left, div) 和 [div+1, right)
 // 遞歸排[left, div)
 QuickSort(array, left, div);
 
 // 遞歸排[div+1, right)
 QuickSort(array, div+1, right);
}

上述為快速排序遞歸實(shí)現(xiàn)的主框架,發(fā)現(xiàn)與二叉樹前序遍歷規(guī)則非常像,同學(xué)們在寫遞歸框架時(shí)可想想二叉
樹前序遍歷規(guī)則即可快速寫出來,后序只需分析如何按照基準(zhǔn)值來對區(qū)間中數(shù)據(jù)進(jìn)行劃分的方式即可。
將區(qū)間按照基準(zhǔn)值劃分為左右兩半部分的常見方式有:

1. hoare版本

【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
看懂了動圖那么我們的代碼實(shí)現(xiàn)如下

// Hoare
int PartSort1(int* a, int left, int right)
{
	//int midi = GetMidi(a, left, right);
	//Swap(&a[left], &a[midi]);

	int keyi = left;
	while (left < right)
	{
		// 找小
		while (left < right && a[right] >= a[keyi])
		{
			--right;
		}

		// 找大
		while (left < right && a[left] <= a[keyi])
		{
			++left;
		}

		Swap(&a[left], &a[right]);
	}

	Swap(&a[keyi], &a[left]);
	return left;
}
// 三數(shù)取中
int GetMidi(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	// left mid right
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])  // mid是最大值
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else // a[left] > a[mid]
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] < a[right]) // mid是最小
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}
void Swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

2.挖坑法

【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
代碼實(shí)現(xiàn)如下

// 挖坑法
int PartSort2(int* a, int left, int right)
{
	int midi = GetMidi(a, left, right);
	Swap(&a[left], &a[midi]);

	int key = a[left];
	// 保存key值以后,左邊形成第一個(gè)坑
	int hole = left;

	while (left < right)
	{
		// 右邊先走,找小,填到左邊的坑,右邊形成新的坑位
		while (left < right && a[right] >= key)
		{
			--right;
		}
		a[hole] = a[right];
		hole = right;

		// 左邊再走,找大,填到右邊的坑,左邊形成新的坑位
		while (left < right && a[left] <= key)
		{
			++left;
		}
		a[hole] = a[left];
		hole = left;
	}

	a[hole] = key;
	return hole;
}
// 三數(shù)取中
int GetMidi(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	// left mid right
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])  // mid是最大值
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else // a[left] > a[mid]
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] < a[right]) // mid是最小
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}
void PrintArray(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{ 
		printf("%d ", a[i]);
	}
	printf("\n");
}

3.前后指針版本

【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
代碼實(shí)現(xiàn)如下

// 前后指針
int PartSort3(int* a, int left, int right)
{
	int midi = GetMidi(a, left, right);
	Swap(&a[left], &a[midi]);

	int prev = left;
	int cur = prev + 1;

	int keyi = left;
	while (cur <= right)
	{
		if (a[cur] < a[keyi] && ++prev != cur)
		{
			Swap(&a[prev], &a[cur]);
		}

		++cur;
	}

	Swap(&a[prev], &a[keyi]);
	return prev;
}
void Swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}
// 三數(shù)取中
int GetMidi(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	// left mid right
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])  // mid是最大值
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else // a[left] > a[mid]
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] < a[right]) // mid是最小
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}

2.3.2 快速排序優(yōu)化

  1. 三數(shù)取中法選key
  2. 遞歸到小的子區(qū)間時(shí),可以考慮使用插入排序
    【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
    快速排序的特性總結(jié):
  3. 快速排序整體的綜合性能和使用場景都是比較好的,所以才敢叫快速排序
  4. 時(shí)間復(fù)雜度:O(N*logN)
    【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
  5. 空間復(fù)雜度:O(logN)
  6. 穩(wěn)定性:不穩(wěn)定
    【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法

三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化

【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
這是題目 我們按照上面所講的(這里我們使用快速排序的方法來實(shí)現(xiàn) 所以代碼可以拷貝粘貼 所以我們就不再繼續(xù)贅述)
【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
看一下這個(gè)圖片 我們定義一個(gè)變量將key保存起來以便后續(xù)比較不會丟失key的數(shù)據(jù)
定義一個(gè)cur表示當(dāng)前數(shù)據(jù) 然后根據(jù)我的藍(lán)色字體部分思考一下 ++L,–R的各自的含義
最后就會形成一個(gè)左邊為小于key的數(shù) 中間為等于key的數(shù) 右邊為大于key的數(shù) 這樣做的好處是如果避免大量的重復(fù)數(shù)據(jù)帶來的不利影響 希望大家能夠理解
這樣以來 我們中間的和key相等的數(shù)據(jù)就不用再次遞歸了 只用遞歸左和右的兩組數(shù)據(jù)了 是不是很方便
但是這里還有一個(gè)問題就是三數(shù)取中我們還要再次優(yōu)化一下避免Leetcode判題太嚴(yán)格導(dǎo)致我們所有測試用例通過了 但是超時(shí)了
下面給大家看一下詳細(xì)代碼和報(bào)錯(cuò)示例
【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化,大話數(shù)據(jù)結(jié)構(gòu),LeetCode刷題,數(shù)據(jù)結(jié)構(gòu),leetcode,算法
希望我的講解能夠最大限度的幫助到你 希望你今天收獲滿滿 我們下一篇文章再見!文章來源地址http://www.zghlxwxcb.cn/news/detail-717705.html

到了這里,關(guān)于【Leetcode刷題(數(shù)據(jù)結(jié)構(gòu))】:三路劃分與三數(shù)隨機(jī)取中的思想實(shí)現(xiàn)快速排序的再優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(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)文章

  • LeetCode 刷題 數(shù)據(jù)結(jié)構(gòu) 鏈表 203 移除鏈表元素

    LeetCode 刷題 數(shù)據(jù)結(jié)構(gòu) 鏈表 203 移除鏈表元素

    Given the? head ?of a linked list and an integer? val , remove all the nodes of the linked list that has? Node.val == val , and return? the new head . Example 1: Example 2: Example 3: Constraints: The number of nodes in the list is in the range? [0, 104] . 1 = Node.val = 50 0 = val = 50 今天leetcode的中文官網(wǎng)比較卡,所以是登錄官網(wǎng)進(jìn)行

    2024年02月14日
    瀏覽(31)
  • java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode566. 重塑矩陣

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode566. 重塑矩陣

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題目錄(劍指Offer、LeetCode、ACM)-----主目錄-----持續(xù)更新(進(jìn)不去說明我沒寫完): https://blog.csdn.net/grd_java/article/details/123063846 代碼:時(shí)間復(fù)雜度O(r*c).除題目要求外,算法本身沒有需要額外空間,空間復(fù)雜度O(1) 從0開始算,一個(gè)3列n行矩陣中,每行就有3個(gè)元

    2024年01月21日
    瀏覽(22)
  • java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode283. 移動零

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode283. 移動零

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題目錄(劍指Offer、LeetCode、ACM)-----主目錄-----持續(xù)更新(進(jìn)不去說明我沒寫完): https://blog.csdn.net/grd_java/article/details/123063846 解題思路 雙指針,用right和left兩個(gè)指針,將非0元素,全部按順序換到數(shù)組前面。left指向左邊非0元素應(yīng)該插入的位置,right找到非

    2024年01月21日
    瀏覽(58)
  • java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode287. 尋找重復(fù)數(shù)

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode287. 尋找重復(fù)數(shù)

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題目錄(劍指Offer、LeetCode、ACM)-----主目錄-----持續(xù)更新(進(jìn)不去說明我沒寫完): https://blog.csdn.net/grd_java/article/details/123063846 解題思路 弗洛伊德判圈法,也就是快慢指針判圈法(龜兔賽跑算法),此算法分為兩個(gè)步驟 判斷是否有環(huán),并得到快慢指針相遇

    2024年01月24日
    瀏覽(27)
  • Leetcode刷題---C語言實(shí)現(xiàn)初階數(shù)據(jù)結(jié)構(gòu)---單鏈表

    Leetcode刷題---C語言實(shí)現(xiàn)初階數(shù)據(jù)結(jié)構(gòu)---單鏈表

    刪除鏈表中等于給定值 val 的所有節(jié)點(diǎn) 給你一個(gè)鏈表的頭節(jié)點(diǎn)head和一個(gè)整數(shù)val,請你刪除鏈表中所有滿足Node.val==val的節(jié)點(diǎn),并返回新的頭節(jié)點(diǎn) 輸入:head = [1,2,6,3,4,5,6], val = 6 輸出:[1,2,3,4,5] 示例 2: 輸入:head = [ ], val = 1 輸出:[ ] 示例 3: 輸入:head = [7,7,7,7], val = 7 輸出:

    2024年02月15日
    瀏覽(94)
  • java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode240. 搜索二維矩陣 II

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode240. 搜索二維矩陣 II

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題目錄(劍指Offer、LeetCode、ACM)-----主目錄-----持續(xù)更新(進(jìn)不去說明我沒寫完): https://blog.csdn.net/grd_java/article/details/123063846 解題思路 法一:把整個(gè)數(shù)組遍歷一遍,時(shí)間復(fù)雜度O(m*n) 法二:每一行用二分搜索,那么時(shí)間復(fù)雜度就是O(m * l o g 2 n log_2{n} l o g

    2024年01月22日
    瀏覽(35)
  • java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode766. 托普利茨矩陣

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode766. 托普利茨矩陣

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題目錄(劍指Offer、LeetCode、ACM)-----主目錄-----持續(xù)更新(進(jìn)不去說明我沒寫完): https://blog.csdn.net/grd_java/article/details/123063846 解題思路 這道題只要換一種理解方式,瞬間就會變的很簡單。 題目描述是每個(gè)元素左上和右下對角線元素都相同。但是,我們發(fā)

    2024年01月25日
    瀏覽(25)
  • java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode667. 優(yōu)美的排列 II

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode667. 優(yōu)美的排列 II

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題目錄(劍指Offer、LeetCode、ACM)-----主目錄-----持續(xù)更新(進(jìn)不去說明我沒寫完): https://blog.csdn.net/grd_java/article/details/123063846 解題思路 題目要求我們返回一個(gè)數(shù)組長度為n的數(shù)組,必須含有1~n的所有數(shù),并且從左到右,相鄰的元素依次相減,它們的差,必

    2024年01月25日
    瀏覽(25)
  • java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode209. 長度最小的子數(shù)組

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode209. 長度最小的子數(shù)組

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題目錄(劍指Offer、LeetCode、ACM)-----主目錄-----持續(xù)更新(進(jìn)不去說明我沒寫完): https://blog.csdn.net/grd_java/article/details/123063846 解題思路 代碼:時(shí)間復(fù)雜度O(n).空間復(fù)雜度O(1)

    2024年01月21日
    瀏覽(96)
  • java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode96. 不同的二叉搜索樹

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題-----LeetCode96. 不同的二叉搜索樹

    java數(shù)據(jù)結(jié)構(gòu)與算法刷題目錄(劍指Offer、LeetCode、ACM)-----主目錄-----持續(xù)更新(進(jìn)不去說明我沒寫完): https://blog.csdn.net/grd_java/article/details/123063846 很多人覺得動態(tài)規(guī)劃很難,但它就是固定套路而已。其實(shí)動態(tài)規(guī)劃只不過是將多余的步驟,提前放到dp數(shù)組中(就是一個(gè)數(shù)組,只

    2024年01月21日
    瀏覽(30)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包