精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

字節一面:非遞歸手寫快速排序

開發 前端
本文中講解的套路就失效了,因此我們需要一種更加通用的方法將此類非尾遞歸代碼轉為遞歸代碼,這種通用的方法是什么呢?

大家好,我是小風哥。

今天給大家講解一道非常有趣的算法面試題,以非遞歸的形式來寫快速排序。

其實這也可以衍生出更多同類問題,非遞歸二叉樹的前序、中序、后序遍歷等等,這些問題的背后的思想是一致的,那就是用棧來手動模擬遞歸調用。

道理很簡單有沒有,一句話就能說清楚,但問題是你真的理解了嗎?該怎樣用棧來手動模擬遞歸調用呢?你的大腦在面對這個問題時有一個清晰的思路嗎?

別著急,我們先從最簡單的快排開始。

快排,quick sort

快速排序想必大家都知道,我們以數組中的某個數字為基準,通常是數組的第一個或者最后一個(當然也可以是其它選擇方式),這里假設以數組的最后一個元素為基準:

圖片

然后將數組中小于該基準的數字放在左邊、將大于該數字的放在右邊:

圖片

經過這一次處理后base就被放到了最終的位置上并得到了兩個子數組:base左邊的數組和base右邊的數組,以同樣的方式處理這兩個子數組即可。

用代碼表示就是這樣:

void quick_sort(vector<int>&arr, int b, int e) {
if (b >= e) return;
int i = b - 1;
for (int k = b; k < e; k++)
if (arr[k] < arr[e])
swap(&arr[++i], &arr[k]);
swap(&arr[++i], &arr[e]);

quick_sort(arr, b, i - 1);
quick_sort(arr, i + 1, e);
}

其中參數中的b和e表示begin和end,也就是范圍。

遞歸版本很簡單有沒有,如果讓你用非遞歸的方式來實現呢?

非遞歸手寫快速排序

想一想這個問題!如果你真正理解遞歸的話那么就應該能寫出來。

我們再來看看這個遞歸寫法。

首先會得到一個問題quick_sort(arr, b, e),我們利用base進行一次劃分后得到兩個子問題:

  • quick_sort(arr, b, i - 1)
  • quick_sort(arr, i + 1, e)

在遞歸版本中這兩個子問題的狀態(所謂的狀態就是要解決哪個子問題,這里用參數中的begin和end來界定)是隨著函數的調用自動保存在棧幀中的,而我們需要用棧這種數據結構來模擬這個過程。

接下來,我們用變量task來表示要處理的子問題,也就是說入棧出棧的都是task,task可以這樣定義:

pair<int, int>

表示要對哪一段數組進行排序,因此使用了pair<int, int>來記錄這段數組的開始和結尾。

由于需要使用棧來追蹤問題的解決順序,因此我們最終這樣定義棧:

stack<pair<int, int>> tasks;

一切準備就緒,是時候創建些任務了,任務的起源是什么呢?很簡單,就是數組本身:

int size = arr.size();
tasks.push(pair<int, int>(0, size - 1));

接下來就是最重要的部分了:

while (!tasks.empty()) {
// 取出棧頂元素
// 處理
// 是否有新的子任務需要push到棧中
}

整體的框架就是這樣,接下來的三個問題就是:

  • 取出棧頂元素
  • 處理
  • 是否有新的子任務需要push到棧中,如果有則push到棧中

第一個問題很簡單,沒什么可說的;第二個問題是說我們該怎樣處理一個子問題,其實也很簡單,就是用base將數組劃分為兩個子數組。

第三個問題是重點,我們該怎么知道接下來是否有新的子任務需要push到棧中呢?

想一想這個問題。。。

如果用base對數組進行劃分后發現數組已經是有序的那么就沒有必要創建子任務了,因為當前的數組已經有序了嘛!否則我們就需要創建子任務。

因此我們必須知道對數組進行劃分后數組是不是已經排好序。

基于上述討論,我們可以這樣實現劃分函數partition:

int partition(vector<int>&arr, int b, int e, bool* sorted) {
if (b > e || b == e) return -1;

int i = b - 1;
for (int j = b; j < e; j++) {
if (arr[j] < arr[e]) {
*sorted = false;
swap(arr[++i],arr[j]);
}
}
swap(arr[++i], arr[e]);

return i;
}

這其實和開始遞歸版本中quick_sort函數里的劃分部分代碼沒什么區別,變化的部分僅在于我們將一次劃分后base所在的下標以及判斷一次劃分后數組是否有序記錄在參數sorted中。

一次劃分后如果sorted的值為true也就是數組已經有序那么我們無需再創建新的子問題,一次劃分后我們得到兩個新的更小的子問題,即:

bool sorted = true;
int p = partition(arr, top.first, top.second, &sorted);

if (sorted) {
continue;
} else {
tasks.push(pair<int,int>(p + 1, top.second));
tasks.push(pair<int,int>(top.first, p - 1));
}

所有問題分析完畢,完整的代碼為:

void quick_sort(vector<int>&arr) {
int size = arr.size();
if (size == 0 || size == 1) return ;
stack<pair<int,int>> tasks;
tasks.push(pair<int,int>(0, size - 1));

int b = 0;

while(!tasks.empty()) {
auto top = tasks.top();
tasks.pop();

bool sorted = true;
int p = partition(arr, top.first, top.second, &sorted);

if (sorted) {
continue;
} else {
tasks.push(pair<int,int>(p + 1, top.second));
tasks.push(pair<int,int>(top.first, p - 1));
}
}
}

運行一下,it works like magic,有沒有!

這段代碼是怎樣運行的?

No,其實一點都不magic,接下來我們仔細看看這段代碼是怎么運行的。

假設當前棧頂元素為(2,9),我們獲取棧頂元素,并將其從中pop掉:

圖片

此時我們要對數組下標2到9的元素進行排序,把末尾的base作為基準進行劃分:

圖片

假設劃分后base放到了下標為5的位置,這樣我們得到了兩個子問題(2,3)以及(4,9):

圖片

由于經過base的劃分后我們判斷出該數組不是有序的(partition函數中sorted參數的作用),因此我們需要將兩個子問題(2,3)以及(4,9)放到棧中:

圖片

就這樣,我們解決了子任務(2,9),并得到了兩個更小的子問題(2,3)以及(4,9),接著while循環繼續從棧中彈出任務并重復上述過程,當棧為空時我們一定能確信數據已經有序了。

這個過程“完全”模擬了上述遞歸函數的調用,這里之所以加了引號,是因為我們的迭代快排版本進行了一點點小小的優化,這個優化是什么呢?

尾遞歸

依然假設遞歸調用到函數quick_sort(2,9),此時的函數棧幀為:

圖片

基于base劃分后依然得到:

圖片

根據遞歸版本的quick_sort實現接著我們需要調用quick_sort(2,3),此時的棧幀為:

圖片

看到非遞歸版本與遞歸版本的不同了吧:

圖片

在非遞歸版本下,對處理子任務(2,9)時會將該任務從棧中pop出來,而遞歸版本則不會pop出quick_sort(2,9)的棧幀,函數quick_sort(2,3)執行完后還會再次回到函數quick_sort(2,9),然后接著調用函數quick_sort(4,9)。

而之所以非遞歸實現可以提前將子任務(2,9)從棧中彈出是因為遞歸版本下所有遞歸調用都位于函數的末尾,這就是所謂的“尾遞歸”。

尾遞歸是一種比較常見的現象,二叉樹的前序遍歷遞歸實現也是這樣:

void tree_travel(Tree* t) {
if (t) {
print(t->value);
tree_travel(t->left);
tree_travel(t->right);
}
}

你可以使用和本文一樣的套路將上述遞歸代碼轉為非遞歸代碼,但是如果是二叉樹的中序遍歷或者后序遍歷呢?

void tree_travel(Tree* t) {
if (t) {
tree_travel(t->left);
print(t->value);
tree_travel(t->right);
}
}

此時,本文中講解的套路就失效了,因此我們需要一種更加通用的方法將此類非尾遞歸代碼轉為遞歸代碼,這種通用的方法是什么呢?

希望本篇對大家理解遞歸、棧、快排有所幫助。

責任編輯:武曉燕 來源: 碼農的荒島求生
相關推薦

2022-03-30 10:10:17

字節碼棧空間

2022-08-13 12:07:14

URLHTTP加密

2024-09-19 08:51:01

HTTP解密截取

2024-11-26 08:52:34

SQL優化Kafka

2022-05-10 22:00:41

UDPTCP協議

2022-01-05 21:54:51

網絡分層系統

2022-08-18 17:44:25

HTTPS協議漏洞

2025-09-03 10:01:05

2022-06-01 11:52:42

網站客戶端網絡

2025-08-18 02:11:00

2024-11-11 10:34:55

2022-05-11 22:15:51

云計算云平臺

2022-11-30 17:13:05

MySQLDynamic存儲

2022-10-19 14:08:42

SYNTCP報文

2024-05-15 16:41:57

進程IO文件

2024-09-04 15:17:23

2022-12-02 13:49:41

2020-09-19 17:46:20

React Hooks開發函數

2009-07-30 14:38:36

云計算

2011-12-23 09:43:15

開源開放
點贊
收藏

51CTO技術棧公眾號

四虎永久在线精品无码视频| 成人性生交xxxxx网站| 国产在线观看无码免费视频| 成人动漫一区| 国产精品久久久久久亚洲毛片| 成人综合网网址| 国产成人无码精品| 成人羞羞网站入口| 欧美精品一区二区三区蜜桃 | 午夜在线视频观看| 麻豆成人免费电影| 97精品欧美一区二区三区| 在线免费观看视频| 国产日韩三级| 欧美三级资源在线| 缅甸午夜性猛交xxxx| 香蕉视频在线看| 不卡一区二区三区四区| 成人中文字幕+乱码+中文字幕| 天天操中文字幕| 欧美在线网站| 中文字幕久热精品在线视频| 精品视频站长推荐| 国产欧美视频在线| 欧美午夜一区二区| 日本毛片在线免费观看| 色呦呦久久久| 中文字幕一区二区三区不卡| 欧美大香线蕉线伊人久久| www.中文字幕| 久久国产人妖系列| 国产精品成人一区二区| 国产区在线观看视频| 欧美 日韩 国产一区二区在线视频| 亚洲香蕉在线观看| 醉酒壮男gay强迫野外xx| 亚洲高清999| 欧美日本国产视频| 亚洲天堂网一区| 欧美magnet| 精品国产乱码久久久久酒店| 国产一区二区三区在线免费| 免费av在线网站| 国产精品亲子伦对白| 欧美午夜欧美| 青青免费在线视频| 91网上在线视频| 精品日本一区二区三区| 无码精品人妻一区二区| www.欧美色图| 久久精品日韩| 神马久久高清| 2022国产精品视频| 麻豆精品传媒视频| 少妇激情av一区二区| 97国产精品videossex| 国产伦精品一区二区| 丰满熟女一区二区三区| 国产精品乡下勾搭老头1| 96精品久久久久中文字幕| 国产精品爽爽久久| 国产在线精品一区二区不卡了 | 日韩在线免费视频观看| 欧美xxxx精品| 偷偷www综合久久久久久久| xxxxx成人.com| 免费成人美女女在线观看| 亚洲精品97| 欧美日韩不卡合集视频| 国产一级一级片| 一本色道久久综合一区 | 亚洲精品男人天堂| 日韩国产欧美在线视频| 国产欧美精品va在线观看| 97精品人妻一区二区三区香蕉| 黄色资源网久久资源365| 亚洲a∨日韩av高清在线观看| 精品毛片在线观看| 91亚洲精品一区二区乱码| 欧美精品欧美精品系列c| 福利视频在线导航| 亚洲欧美色图小说| 福利视频免费在线观看| 手机av在线| 欧美亚一区二区| 又黄又爽又色的视频| 欧美男男freegayvideosroom| 亚洲欧美精品suv| 北条麻妃在线观看视频| 国产精品分类| 国产成人精品999| 国产精品久久久久久免费免熟 | 国产91色在线|亚洲| 天堂av一区二区三区| 久久精品免费在线观看| 99中文字幕在线观看| 日本在线播放一二三区| 欧美理论片在线| 最近中文字幕无免费| 日韩精品中文字幕第1页| 欧美老妇交乱视频| 午夜久久久久久久久久影院| 国产在线视频不卡二| 欧美精彩一区二区三区| 91在线中字| 91国产成人在线| 久久久无码人妻精品无码| 亚洲理论电影| 久久久久久久久久国产精品| 亚洲视频久久久| av不卡在线观看| 欧美少妇在线观看| 暖暖成人免费视频| 欧美mv日韩mv国产网站| 国产一级淫片久久久片a级| 一本色道久久| 不卡日韩av| 日韩在线观看www| 欧美性xxxxxxx| av影片在线播放| 97精品国产| 国产精品高潮在线| 午夜视频www| 亚洲一卡二卡三卡四卡无卡久久 | 国产成人在线观看网站| 国产一区二区调教| 亚洲资源视频| www.26天天久久天堂| 日韩毛片在线看| 国产精品成人网站| 国产精品自拍av| 中文字幕欧美日韩一区二区三区| 国产精品亚洲一区二区三区在线观看| 精品国产免费人成在线观看| 无码人妻精品一区二区三区夜夜嗨| 日本伊人午夜精品| 日韩精品无码一区二区三区| 女人高潮被爽到呻吟在线观看| 欧美videos大乳护士334| 免费成年人视频在线观看| 免费成人在线视频观看| 先锋影音网一区| 日韩国产网站| 亚洲最大中文字幕| 免费av中文字幕| 久久久99精品久久| 免费大片在线观看| 久久99免费视频| 国产精品99久久久久久人| 麻豆影视在线| 欧美在线你懂得| 美国黄色特级片| 欧美aaaaa成人免费观看视频| 水蜜桃亚洲一二三四在线| 欧美性片在线观看| 色婷婷久久av| 999av视频| 亚洲综合色成人| 亚洲高清无码久久| 一区二区福利| 欧洲亚洲一区二区三区四区五区| 欧美xxx网站| 色先锋资源久久综合5566| 在线免费观看av片| 亚洲乱码中文字幕| 亚洲av无码一区东京热久久| 夜夜嗨网站十八久久 | 天堂√在线中文官网在线| 狠狠躁18三区二区一区| 白白色免费视频| 久久精品国产久精国产爱| 六月婷婷激情网| 国产精品99久久免费观看| 欧美在线观看网址综合| 福利在线播放| 欧美一二三区在线观看| 国产无套内射又大又猛又粗又爽| 99精品视频在线播放观看| caoporn超碰97| 51精产品一区一区三区| 国产精品免费一区二区三区| 中文av在线全新| 日韩在线激情视频| 欧美一级片免费| 色综合久久中文综合久久牛| 国产人与禽zoz0性伦| 成人网页在线观看| 亚洲精品中文字幕无码蜜桃| 欧美在线免费| 欧美一区二区三区在线免费观看| 99久久这里有精品| 97人人做人人爱| 天堂中文8资源在线8| 精品国产乱码久久久久久久| av毛片在线免费观看| 亚洲三级视频在线观看| 性高潮久久久久久久| 国产麻豆精品在线观看| 一本大道熟女人妻中文字幕在线| 色综合天天爱| 国产一区二区三区高清| 日韩黄色在线| 欧美在线亚洲一区| 亚洲h片在线看| 伊人一区二区三区久久精品| 国产综合无码一区二区色蜜蜜| 色天天综合久久久久综合片| 久久国产在线视频| 国产精品视频观看| 新91视频在线观看| 成人在线视频首页| 不卡中文字幕在线观看| 亚洲综合99| 无码粉嫩虎白一线天在线观看| 欧美午夜精彩| 欧美精彩一区二区三区| 果冻天美麻豆一区二区国产| 成人福利网站在线观看| 日韩高清在线| 欧美中文字幕在线| 成人免费观看在线观看| 久久国产精品影视| 浪潮av一区| 在线看日韩欧美| 免费播放片a高清在线观看| 亚洲国产精品推荐| 亚洲精品视频91| 日韩欧美国产精品一区| 亚洲无码精品在线播放| 91国偷自产一区二区使用方法| 日本三级视频在线| 亚洲国产综合在线| 青春草免费视频| 亚洲人成在线播放网站岛国| av片在线免费看| 免费看一级一片| 国产精品一区专区| 亚洲无在线观看| 免费看欧美美女黄的网站| 欧美精品第三页| 久久精品女人| 国产综合免费视频| 久久精品三级| 黄色一级二级三级| 久久天堂成人| 午夜精品在线免费观看| 石原莉奈在线亚洲三区| 99免费视频观看| 首页亚洲欧美制服丝腿| 超碰网在线观看| 视频精品一区二区| 污污的网站18| 久久97超碰色| 午夜诱惑痒痒网| 国产酒店精品激情| 国产精久久久久| 粉嫩aⅴ一区二区三区四区| 亚洲av成人精品一区二区三区| 成人va在线观看| 三叶草欧洲码在线| 久久精品视频免费观看| 中文字幕伦理片| 日韩毛片在线免费观看| 真实国产乱子伦对白在线| 亚洲国产精品麻豆| 国产毛片aaa| 在线一区二区三区四区五区| 在线观看视频二区| 欧美一区二区三区在线看| 亚洲成人中文字幕在线| 精品国产免费一区二区三区香蕉| 四虎在线观看| 原创国产精品91| 国产精品久久麻豆| 欧美丰满少妇xxxx| 日韩伦理三区| 国产日韩欧美在线| 国内视频在线精品| 日韩欧美一区二区三区久久婷婷| 欧美大黑bbbbbbbbb在线| www.69av| 先锋亚洲精品| 91精品国产三级| 久久亚洲精华国产精华液| 国产jizz18女人高潮| 亚洲综合在线视频| 日韩电影在线观看一区二区| 欧美精品成人一区二区三区四区| 性生交生活影碟片| 亚洲色图欧美制服丝袜另类第一页| a√在线中文网新版址在线| 欧美高清videos高潮hd| 桃子视频成人app| 亚洲淫片在线视频| 国产精品免费99久久久| 国产精品久久成人免费观看| 国产精品久久777777毛茸茸| 岛国av免费在线| 91丨九色丨蝌蚪丨老版| 国产精品视频看看| 欧美日韩亚洲一区二区三区| 一区二区三区免费在线| 日韩av在线播放资源| 国产日产一区二区| 日韩免费中文字幕| 国产精品中文字幕制服诱惑| 亚洲午夜精品国产| 一区二区黄色| 亚洲女人在线观看| 久久精品视频免费观看| 国产一级做a爰片在线看免费 | 中文在线字幕免费观| 亚洲精品一区二区三区蜜桃下载 | 美女一区二区在线观看| 影音先锋欧美资源| 午夜影院日韩| a天堂视频在线观看| 亚洲精品伦理在线| 亚洲无码精品国产| 亚洲天堂av在线播放| 成人免费网站观看| 97人摸人人澡人人人超一碰| 日韩中文首页| 国产成人无码av在线播放dvd| 不卡大黄网站免费看| 三级影片在线看| 欧美日韩mp4| h网站在线免费观看| 日韩免费观看在线观看| 亚洲最好看的视频| 亚洲国产精品成人天堂| 风间由美一区二区三区在线观看| 女性裸体视频网站| 欧美久久久久免费| 免费av不卡| 国产在线精品一区免费香蕉 | 亚洲精品天天看| 国产美女高潮在线| 国产一区免费| 亚洲三级网站| 三级男人添奶爽爽爽视频| 亚洲国产另类av| 成人黄色免费视频| 欧美黄网免费在线观看| 日韩精品一区二区三区中文字幕| av磁力番号网| 国产一区二区中文字幕| 青青草激情视频| 日韩精品专区在线影院重磅| 最新超碰在线| 国产精品一区在线观看| 尹人成人综合网| 性欧美丰满熟妇xxxx性仙踪林| 欧美日韩亚洲高清| 男人的天堂在线| 国产精品高潮呻吟久久av无限| 青青草国产免费一区二区下载| 亚洲欧美激情网| 国产精品久久午夜夜伦鲁鲁| 91丨九色丨丰满| 欧美激情亚洲激情| 欧美一区二区三区久久| 无码人妻丰满熟妇区毛片18| 国产亚洲欧美色| 怡红院男人天堂| 伦理中文字幕亚洲| 国产精品45p| 北条麻妃视频在线| 亚洲欧洲精品一区二区三区不卡| 国产高清在线免费| 97国产在线视频| 国产精品亚洲人成在99www| 久久婷婷综合色| 一区二区三区视频在线观看| 婷婷五月综合激情| 国产精品va在线播放我和闺蜜| 欧美顶级大胆免费视频| 极品人妻一区二区| 日韩欧美亚洲国产一区| 久草免费在线| 国产精品一区免费观看| 日本伊人精品一区二区三区观看方式| 人与动物性xxxx| 亚洲国产欧美在线成人app| 偷拍视频一区二区三区| 一区二区不卡在线视频 午夜欧美不卡'| 国产麻豆欧美日韩一区| 四虎成人在线观看| 久久在线精品视频| 奇米777国产一区国产二区| www.com黄色片| 亚洲国产日韩a在线播放| 国产福利在线看| 国产精品久久亚洲| 蜜臀va亚洲va欧美va天堂| 久久亚洲AV无码| 中文字幕亚洲综合久久筱田步美| 亚洲欧美日本国产| mm1313亚洲国产精品无码试看| 亚洲精品成人精品456|