精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

精品人伦一区二区三区蜜桃网站| 国产在线视频精品一区| 精品视频久久久久久久| 久久久久久久久久福利| 免费在线看黄| 成人97人人超碰人人99| 国产精品18久久久久久首页狼 | 妺妺窝人体色www看人体| av女名字大全列表| 精品一区二区三区香蕉蜜桃| 国内精品久久久久| 在线观看天堂av| 国产精品传媒| 欧美精选一区二区| 国产亚洲综合视频| 黄视频在线观看网站| 久久中文字幕电影| 亚洲在线www| 日本成人一级片| 影音先锋久久精品| 色婷婷av一区二区三区久久| 亚洲一级av无码毛片精品| 激情中国色综合| 欧美午夜电影在线| 日本一区午夜艳熟免费| 欧美69xxx| 国产午夜精品理论片a级大结局| av一区二区三区四区电影| 波多野结衣在线电影| 极品少妇一区二区三区| 久久精品小视频| 久久久久久久毛片| 亚洲免费专区| 亚洲精品成人网| 国产裸体视频网站| 色综合视频一区二区三区日韩 | 97超碰国产在线| 久久亚洲视频| 57pao成人永久免费视频| 69av.com| 欧美一区成人| 久久激情五月丁香伊人| 日本高清黄色片| 国产精品三级| 亚洲欧美日韩中文视频| 最近中文字幕无免费| 开心激情综合| 亚洲福利影片在线| 亚洲午夜精品在线观看| 国产精品成人3p一区二区三区| 欧美午夜精品一区| 美女网站免费观看视频| 欧美电影网站| 在线免费观看视频一区| av免费在线播放网站| 成人免费图片免费观看| 亚洲国产精品一区二区www| 777久久精品一区二区三区无码| sm国产在线调教视频| 亚洲三级久久久| www.-级毛片线天内射视视| 国产在线高清理伦片a| 亚洲免费观看高清| wwwwww欧美| 17videosex性欧美| 五月婷婷综合激情| 69堂免费视频| 欧美va在线| 欧美视频在线一区| 亚洲五月激情网| 国产精品15p| 亚洲精品少妇网址| 中字幕一区二区三区乱码| 日韩dvd碟片| 日韩一区二区三区xxxx| 婷婷在线精品视频| 中文欧美日韩| 国产精品扒开腿做爽爽爽男男 | 日韩av在线精品| 蜜桃传媒一区二区亚洲| 国产高清一区| 久久久久成人精品| 国产精品第5页| 六月婷婷色综合| 91精品网站| 四虎影视2018在线播放alocalhost| 91在线视频18| 一区二区视频在线播放| 久久99亚洲网美利坚合众国| 色综合av在线| 超碰在线免费av| 神马久久影院| 日韩中文有码在线视频| 久久免费小视频| 日韩精品电影在线| 97视频资源在线观看| 亚洲欧美自偷自拍| 亚洲欧洲成人自拍| 免费黄色日本网站| 久久久久久爱| 亚洲三级 欧美三级| 岛国毛片在线观看| 性8sex亚洲区入口| 亚洲一区二区中文字幕| 免费在线观看一级毛片| 亚洲精品视频在线看| 日韩精品一区中文字幕| 日韩成人在线看| 一本色道久久综合狠狠躁篇的优点 | 成人欧美一区二区三区黑人麻豆| 成人免费性视频| 成人全视频在线观看在线播放高清| 精品久久久久一区| 国产在线免费看| 国产精品入口| 国产高清自拍一区| 色综合久久久久综合一本到桃花网| 亚洲mv在线观看| 成人免费黄色av| 欧美久久综合网| 91av在线免费观看| 午夜精品在线播放| 综合在线观看色| 亚洲精品高清无码视频| 久久香蕉精品香蕉| 欧美国产日韩中文字幕在线| 在线免费看毛片| 久久精品人人做| 91精品91久久久中77777老牛| 我要色综合中文字幕| x99av成人免费| 中文字幕一区在线播放| 99re视频这里只有精品| 被灌满精子的波多野结衣| 91精品国产一区二区在线观看| 国产亚洲美女精品久久久| 日韩精品1区2区| www.99精品| 日韩五码在线观看| 成人资源在线| 久久久噜噜噜久久中文字免| 国产极品久久久| 一区二区三区日韩精品| 一本之道在线视频| 亚洲高清影视| 96sao精品视频在线观看| 免费人成在线观看播放视频| 欧美猛男gaygay网站| 九九热久久免费视频| 免费的成人av| 一区二区免费在线视频| 99久久久国产| 久久精品最新地址| 99久久久久久久| 亚洲精品写真福利| 亚洲午夜久久久久久久久| 亚洲福利免费| 美乳视频一区二区| 天然素人一区二区视频| 中文字幕无线精品亚洲乱码一区 | 91爱视频在线| 青青操视频在线| 色哟哟一区二区在线观看| 女女互磨互喷水高潮les呻吟| 欧美aⅴ一区二区三区视频| 一级二级三级欧美| 久久三级中文| 国内精品久久久久伊人av| 午夜影院在线视频| 欧美性xxxx在线播放| 手机看片福利视频| 精品一区二区在线播放| 精品无码av无码免费专区| 国产精品xxxav免费视频| 26uuu亚洲国产精品| 国产视频三级在线观看播放| 欧美日韩三级一区| 欧美精品99久久久| 91啪九色porn原创视频在线观看| 91av在线免费播放| 91久久电影| 国产女人水真多18毛片18精品| 在线能看的av网址| 在线日韩日本国产亚洲| 精品国产va久久久久久久| 亚洲va国产va欧美va观看| 日韩av片在线| 粉嫩高潮美女一区二区三区| 国产xxxxx在线观看| 日韩中文在线电影| 国产午夜精品在线| av成人在线播放| 久久久久国产精品免费网站| 国产黄色在线| 日韩精品一区二区三区四区视频 | 日韩精品欧美一区二区三区| 久久国际精品| 国产成人亚洲精品| 日本资源在线| 中文欧美在线视频| 少妇精品视频一区二区| 欧美三级电影精品| 在线观看 中文字幕| 国产精品成人免费| 狠狠人妻久久久久久综合蜜桃| 久久精品国产999大香线蕉| 欧美精品久久久久久久久久久| 成人精品影视| 久草一区二区| 亚洲日本va| 91精品国产综合久久香蕉最新版 | 91久久一区二区| 久久久久久久久精| 国产精品国产三级国产a | **欧美大码日韩| 91精品人妻一区二区| 国产+成+人+亚洲欧洲自线| av网站在线不卡| 中文在线一区| 精品少妇在线视频| 国产精品久久观看| 日本中文不卡| 天天躁日日躁成人字幕aⅴ| 91免费看网站| 91成人小视频| 国产精品中文久久久久久久| 激情都市亚洲| 2021国产精品视频| sm在线观看| 欧美成人一二三| 国产在线观看a视频| 中文字幕免费精品一区| 精品推荐蜜桃传媒| 日韩成人在线网站| 欧美熟妇乱码在线一区| 日韩欧美123| 国产高清精品软件丝瓜软件| 欧美精品丝袜中出| 国产一区二区三区在线观看| 日本精品视频一区二区| jizz国产在线观看| 欧美视频在线免费| 6080午夜伦理| 在线视频你懂得一区二区三区| 亚洲午夜18毛片在线看| 欧美性开放视频| 青青视频在线免费观看| 色婷婷av一区二区三区之一色屋| 日韩视频在线观看一区| 欧美三级免费观看| 天天干,天天干| 欧美午夜理伦三级在线观看| 在线观看中文字幕2021| 亚洲第一区色| 日韩中文字幕精品视频| 福利视频在线播放| 永久免费看mv网站入口亚洲| 大乳在线免费观看| 中文字幕在线看视频国产欧美在线看完整 | 亚洲精品影视在线观看| 日本又骚又刺激的视频在线观看| 日韩电影在线观看永久视频免费网站| 日本高清中文字幕二区在线| 亚洲人成绝费网站色www| 成人资源www网在线最新版| 日韩一区二区三区xxxx| 一二三四区在线观看| 久久久亚洲精选| 亚洲国产福利| 国产精品三级美女白浆呻吟| 国产日韩在线观看视频| 懂色一区二区三区av片| 精品淫伦v久久水蜜桃| 欧美一区三区二区在线观看| 日韩1区在线| 日韩亚洲欧美一区二区| 夜夜嗨av一区二区三区网站四季av| 久久久久久久激情| 美女在线视频一区| 日韩精品国产一区| 91麻豆swag| 国产中文字幕久久| 亚洲午夜免费视频| 欧美a视频在线观看| 欧美电影一区二区三区| 黄片毛片在线看| 国产午夜精品美女视频明星a级| 日本视频在线观看| 韩国美女主播一区| 九九九精品视频| 国产欧美日韩综合一区在线观看| 精品国产乱码| 男人天堂av片| 麻豆国产欧美日韩综合精品二区 | 欧美交a欧美精品喷水| 色狠狠久久av五月综合|| 欧美久久一级| 不卡av免费在线| 成人免费看的视频| 国产主播av在线| 精品久久久久久久大神国产| 亚洲视频中文字幕在线观看| 亚洲国产又黄又爽女人高潮的| 亚洲成人三级| 欧美中文在线视频| 欧美特黄不卡| 亚洲第一在线综合在线| 亚洲久久在线| 9191在线视频| 综合欧美一区二区三区| 久久久久久久久影院| 91精品国产手机| 99reav在线| 奇门遁甲1982国语版免费观看高清 | 欧美日韩国产中文| 三级黄视频在线观看| 欧美国产在线电影| 亚洲网站三级| 日韩精品久久久免费观看 | 中文字幕22页| 国产亚洲成aⅴ人片在线观看| 国产一级二级三级| 欧美久久一二区| 懂色一区二区三区| 热re91久久精品国99热蜜臀| 久久精品亚洲成在人线av网址| 黄色网址在线免费看| 日韩成人av影视| 久久精品成人av| 午夜伦理一区二区| 亚洲精品国产手机| 欧美日韩成人网| 国产高清视频一区二区| 一区二区三区av| 奇米影视7777精品一区二区| 丰满少妇一区二区三区| 亚洲成a天堂v人片| 丰满人妻妇伦又伦精品国产| 欧美成人在线影院| 懂色av色香蕉一区二区蜜桃| 久久免费看毛片| 国内成人精品2018免费看| 亚洲天堂网av在线| 欧美精品第一页| 黄网页免费在线观看| 91欧美精品午夜性色福利在线 | 国产精品后入内射日本在线观看| 成人午夜av影视| 国产一级大片在线观看| 精品国产乱码久久久久久1区2区| 青春草视频在线| 国产精品av一区| 亚洲日本国产| 在线免费观看成年人视频| 欧美性猛交xxxx黑人猛交| 欧美拍拍视频| 国产精品久久久久影院日本| 欧美残忍xxxx极端| 久久久久久久久久久久久久久国产| 国产精品私人自拍| 国产精品一品二区三区的使用体验| 久久影院模特热| 91成人午夜| 亚洲中文字幕无码中文字| 久久久久国产精品免费免费搜索| 成人黄色三级视频| 久久久精品国产一区二区| 日韩成人在线观看视频| 999在线观看视频| 久久男人中文字幕资源站| 最新中文字幕免费| 美女啪啪无遮挡免费久久网站| 色妞ww精品视频7777| 精品久久一二三| 欧美国产日韩一二三区| 国产女人高潮时对白| 午夜精品久久久99热福利| 免费看av成人| 亚洲自拍第三页| 黄色成人在线免费| 欧洲不卡av| 国产伦精品一区二区三区高清版| 久久久久久婷| 天天看片中文字幕| 精品中文视频在线| 四虎地址8848精品| 亚洲人成无码网站久久99热国产| 国产午夜精品久久| 国产高潮在线观看| 国产成人av在线播放| 欧美在线网址| 制服 丝袜 综合 日韩 欧美| 日韩一级片在线播放| 肉色欧美久久久久久久免费看| 亚洲欧美一二三| 久久综合九色综合97婷婷女人| 国产日本精品视频| 国产成人一区二区三区小说| 欧美激情日韩| 亚洲色图日韩精品|