国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

如何利用快排的小技巧,解決算法難題?

開發 前端
通過合并排序和快速排序,可以得出結論,數組其實是另外一種形式的二叉樹,只不過有時候需要我們動態地把左/右子樹給切分出來,不同的切分方式,可以解決不同的問題。

快速排序采用的是分治思想,即在一個無序的序列中選取一個任意的基準元素pivot,利用pivot將待排序的序列分成兩部分,前面部分元素均小于或等于基準元素,后面部分均大于或等于基準元素,然后采用遞歸的方法分別對前后兩部分重復上述操作,直到將無序序列排列成有序序列。

今天就為大家帶來面試中經常出現排序算法的深度解析。

快速排序本質上是一個前序遍歷

上一篇文章中講到,合并排序本質上和二叉樹后續遍歷非常類似,而快速排序本質上和二叉樹的前序遍歷非常類似。

首先你還先回憶一下二叉樹的前序遍歷:

// 遞歸
function preOrder(root, array = []) {
  if (root === null) return null;
  array.push(root.val);
  postOrder(root.left, array);
  postOrder(root.right, array);
}

這里可以將代碼拆分為三部分:

// 邊界處理
if (root === null) return null;
// 根節點信息處理
array.push(root.val);
// 根節點的信息,傳遞給左右子樹。
postOrder(root.left, array);
postOrder(root.right, array);

邊界處理先不提,二叉樹的前序遍歷,有兩個重點的特點:

  • 根節點的信息;
  • 根節點的信息,傳遞給左右子樹。

簡單利用偽代碼表示就是:

function 前序遍歷():
    獲取根節點信息;
    將根節點的信息傳遞左右子樹/左右子數組;

快速排序和前序遍歷類似,這個偽代碼對于快速排序同樣成立。

并且對于排序算法來說,排序也就意味著有序,有序性就是信息,因此,我們要做的事情就是把能拿到的有序信息,傳遞給左子數組和右子數組。

有序性

那在排序算法中,如果利用有序性了? 其實有序性的就是選擇一個數 X,并且利用這個數,將數組分成三部分:

  • 小于 X 的部分;
  • 等于 X 的部分;
  • 大于 X 的部分;

左右子樹/子數組的處理

對于到二叉樹來說,小于 X 的部分也就是二叉樹的左子樹,等于 X 的部分就是二叉樹的根節點,大于 X 的部分就是二叉樹的右子樹。

二叉樹對于子樹的處理,就是利用遞歸的方式來進行處理。

postOrder(root.left);
postOrder(root.right);

排序算法對于子數組的處理,同樣也是遞歸地處理左子數組和右子數組。 相對于二叉樹的前序遍歷來說,快速排序的左右子區間是由切分動態生成的,并不像二叉樹那樣由指針固定。并且對于根結點的處理,需要執行“三路切分”操作,將一個數組切分為三段;

所以總結一下,又講回到前面的偽代碼:

function 前序遍歷/快速排序():
    獲取根節點信息;
    將根節點的信息傳遞左右子樹/左右子數組;

并且前序遍歷/快速排序的特點可以總結為以下 3 點:

  • 劃分子結構
  • 根節點的信息處理
  • 將根節點的信息,傳遞給左右子樹/左右子數組。

1. 劃分子結構

對于二叉樹而言,子樹的劃分是天然的,已經在數據結構里面約定好了,比如 Node.left、Node.right。

root.left
root.right 

可以直接通過樹的子節點拿

但是對于數組而言,劃分子結構,也就是找一個節點,將數組切分為幾份,切分的時候,如果想到達最優的效率,那么將數組切為平均的兩半效率應該是最高的(可以聯想到二叉平衡樹的效率)。但是快排不能保證選擇一個數,就一定能將數組切分成為兩半,所以它有自己特殊的處理。

利用 x 將數組分為三份
左子數組 = [小于 x 的部分] = [b, l)
根節點 = [等于 x 的部分] = [l, i)
右子數組 = [大于 x 的部分] = [i, e)

2. 根節點的信息處理

對于二叉樹來說,根節點就是當前節點,也節點的處理也即是收集節點信息。

node
// 根節點信息處理
array.push(root.val);

而排序算法的"根節點"也就是選擇的元素,并且排序算法會通過劃分的子結構和選中的元素來進行排序處理也就是上面說的特殊處理;對于排序算法來說,"根節點"和劃分子結構息息相關。

if (a[i] < x) {
    // 小于 x 的部分
} else if (a[i] === x) {
    // 等于 x 的部分
} else {
    // 大于 x 的部分
}

3. 將根節點的信息,傳遞給左右子樹/左右子數組

二叉樹前序遍歷好說,通過遞歸的方式處理左右子樹。

// 二叉樹的前序遍歷拿左右子樹的信息
preOrder(root.left);
preOrder(root.right);

而排序算法需要分別對左子數組和右子數組進行排序,那么類似的對子數組的排序應該也只需要遞歸就可以了。

// 快速排序去拿左右子數組的信息
qsort(a, b, l);
qsort(a, i, e);

最后,不管是二叉樹還是快速排序都要考慮一下邊界:

二叉樹的邊界就是節點不能為空。

if (root === null) return null;

快速排序的邊界就是:

  • 當 b >= e,說明這個區間是一個空區間,沒有必要再排序;
  • 當 b + 1 === e,說明只有一個元素,也沒有必要排序。
if (b > e || b + 1 >= e) {
  return;
}

小結

對于二叉樹來說,代碼相對比較簡單。

function preOrder(root, array = []) {
  // 邊界處理
  if (root === null) return null;
  // 第一步:劃分子結構,二叉樹在結構上已經劃分了子結構 root.left、root.right 可以直接通過樹的子節點拿
  // 第二步:根節點的信息處理
  array.push(root.val)
  // 第三步:將根節點的信息,傳遞給左右子樹/左右子數組(遞歸的方式)
  postOrder(root.left, array);
  postOrder(root.right, array);
}

對于快速排序來說,如何劃分子結構?如何到達最優的效率?都是在寫算法時需要注意的。

// 交換數組中兩個元素的值 
function swap(A, i, j) {
  const t = A[i];
  A[i] = A[j];
  A[j] = t;
}
function qsort(a, begin, end) {
    // 邊界情況
   if (b > e || b + 1 >= e) {
     return 
   }
 /*********************核心代碼****************************/
 // 第一步:劃分子結構
    const mid = b + ((end - begin) >> 1);
 // 第二步:獲取根節點信息 x
 const x = a[mid];
 // 根據 x 將數組一分為三 【三路切分】
 let l = begin;
 let i = begin;
 let r = end - 1;
    while(i < r) {
        if (a[i] < x) {
            // 小于 x 的部分
            swap(a, l++, i++);
        } else if (a[i] === x) {
            // 等于 x 的部分
            i++;
        } else {
            // 大于 x 的部分
            swap(a, r--, i);
        }
    }

 // 第三步:將根節點的信息傳遞左右子子樹
 qsort(a, b, l);
 qsort(a, i, e);
 /*********************核心代碼****************************/
}
// 主函數,將數組nums排序 
function quickSort(nums) {
  if (nums == null)
    return;
  qsort(nums, 0, nums.length);
}

這里可以思考一下,為什么我們在節點排序處理是通過 swap 操作?它和時間復雜度和空間復雜度有什么關系?

while(i < r) {
    if (a[i] < x) {
        // 小于 x 的部分
        swap(a, l++, i++);
    } else if (a[i] === x) {
        // 等于 x 的部分
        i++;
    } else {
        // 大于 x 的部分
        swap(a, r--, i);
    }
}

總結

通過合并排序和快速排序,可以得出結論,數組其實是另外一種形式的二叉樹,只不過有時候需要我們動態地把左/右子樹給切分出來,不同的切分方式,可以解決不同的問題。大家也可以自己思考和嘗試,看看還能不能發現更多排序的特點和巧妙用法,并且將它們總結下來。歡迎大家一起在評論區交流。

參考

責任編輯:武曉燕 來源: 不愛吃貓的魚er
相關推薦

2023-08-07 12:52:04

模型免費商用技術

2021-03-18 12:08:22

概率問題算法前端

2018-05-04 13:51:14

Facebookhashtag數據集

2022-01-20 15:23:23

區塊鏈技術數字資產

2011-05-03 15:52:29

噴頭打印機

2017-10-11 17:59:35

A10峰會

2023-07-03 10:34:13

2011-02-14 17:09:17

MegastoreNoSQL

2024-04-02 11:37:59

AGI網絡模型GAN

2020-09-17 14:52:31

微信阿里云金融

2023-05-30 13:57:52

模型速度

2017-10-30 17:25:11

javascript

2022-02-15 15:36:24

區塊鏈倉儲技術

2015-07-01 09:47:38

2022-09-14 15:24:57

typescript快排

2013-11-13 14:33:10

hadoop分布式系統

2010-10-21 15:57:37

SQL Server無

2015-04-03 09:41:17

運維工具政府網站SaaS應用

2013-02-27 09:16:34

2018-05-17 15:55:30

點贊
收藏

51CTO技術棧公眾號

www婷婷av久久久影片| 伊人久久综合一区二区| 成人久久视频在线观看| 日本高清视频一区二区三区| 蜜臀久久99精品久久久久宅男| 妞干网这里只有精品| 久久久av毛片精品| 在线看三级网站视频| 91精品视频网| 国产精品久久久久久妇女| 午夜精品三级视频福利| 自拍偷拍欧美专区| 一本久道久久综合| 国产欧美日韩在线观看| 在线国产日本| 亚洲韩国青草视频| aaa国产精品视频| 91精品国产综合久久香蕉最新版| 亚洲欧洲日本一区二区三区| 在线观看成人免费| 亚洲欧美在线视频观看| 三区四区在线视频| 欧美精品一区二区三区国产精品| 国产精品久久天天影视| 樱花www成人免费视频| 中国日韩欧美久久久久久久久| 亚洲一区在线日韩在线深爱| 久久久国产精品不卡| 欧美巨猛xxxx猛交黑人97人| 久久久久久久久久久福利| 6080亚洲理论片在线观看| 色妞久久福利网| 国产欧美精品在线| 日韩成人午夜精品| 亚洲成色www.777999| 在线观看国产精品网站| 精品123区| 国产精品久久久久91| 久久66热re国产| www污污在线| 亚洲人午夜精品免费| 欧美xxxx中国| 成人午夜视频在线观看免费| 欧美日韩精品二区| 国产成人a视频高清在线观看| 国产欧美日韩中文字幕在线| 国产毛片一区二区| 久久久久久高清| 韩日精品视频一区| 91在线观看免费高清完整版在线观看| 国产精品传媒麻豆hd| 成人免费在线视频| 亚洲激情一区二区| 一区二区三区四区视频免费观看 | 国产亚洲欧美日韩一区二区| 亚洲伊人春色| 亚洲第一在线综合网站| www.成人爱| 亚洲一区久久久| 国产日产亚洲精品系列| 中文字幕av一区二区三区高| 真实国产乱子伦对白视频| 午夜激情久久| 国产精品视频yy9099| 成人av动漫| 91在线免费网站| 青青青国产精品一区二区| 日韩激情中文字幕| 色黄视频在线| 欧美成在线观看| 久久99国产乱子伦精品免费| 视频国产在线观看| 91精品国产色综合| 99精品久久只有精品| h片在线观看视频免费免费| aaa级精品久久久国产片| 一区二区在线观看视频| 亚洲伊人精品酒店| 中文字幕人妻熟女人妻洋洋| 日韩精品一区二区三区蜜臀| 黄色成人在线网站| 日本高清中文字幕二区在线| 2021国产精品视频| 久久免费国产精品| 成人在线观看免费视频| 亚洲国产欧洲综合997久久| 欧美视频三区在线播放| 99久久99热这里只有精品| 成全视频全集| 97在线观看免费高清| 国产欧美久久久精品影院| 亚洲一区导航| 一本大道熟女人妻中文字幕在线| 国产一区二区动漫| 国产精品中文字幕日韩精品| 黑人极品ⅴideos精品欧美棵| 久久99九九| 欧美欧美欧美欧美首页| 好看的日韩av电影| 狠狠狠综合7777久夜色撩人| 国产精品日韩欧美综合| 亚洲一二三专区| 日韩黄色大片网站| 天堂中文在线资| 成人三级在线| 97久久精品一区二区三区的观看方式 | 91色p视频在线| 亚洲综合偷拍欧美一区色| 久久99国内| 在线播放av片| 国产精品v欧美精品∨日韩| 欧美福利一区二区| 全部av―极品视觉盛宴亚洲| 日本黄色免费在线| 日本韩国欧美在线观看| 欧美激情三级免费| 亚洲二区在线视频| 欧美精品aa| 黄色成人在线网| 国产精品999视频| 欧美日韩福利电影| 亚洲综合在线第一页| 亚洲网址在线| 乡村艳史在线观看| 日本精品www| 国产日韩欧美自拍| 精品剧情在线观看| 久久久噜噜噜久久人人看| 日韩1区2区| 成人免费高清观看| 91淫黄看大片| 亚洲综合自拍一区| 亚洲美女av在线| 国产精品久久看| 99热免费精品在线观看| 亚洲男人av| 日本1区2区| 亚洲精品高清国产一线久久| 亚洲性猛交xxxxwww| 国产精品久久99| 9久re热视频在线精品| 99re久久| 黄色电影免费在线看| 4444在线观看| 成人免费福利视频| 色综合亚洲精品激情狠狠| 亚洲综合在线视频| 国产一区在线观看麻豆| 欧美男gay| 最新欧美色图| 污污网址在线观看| 国产成a人亚洲精v品在线观看| 国产精品午夜一区二区欲梦| 亚洲成人久久久| 亚洲国产cao| www.欧美日韩| 亚洲裸体俱乐部裸体舞表演av| 国外成人福利视频| 日韩av成人| 18禁免费观看网站| 成人欧美一区二区三区视频| 影音先锋日韩有码| 欧美在线影院一区二区| a在线播放不卡| 久久精品30| 九九热爱视频精品视频| 午夜av不卡| 可以在线观看的av| 日韩免费高清在线| 日韩三级电影| 国产日韩精品一区二区| 色噜噜国产精品视频一区二区| 精品久久久久久久久久ntr影视 | 亚洲春色在线视频| 国产成人91久久精品| 日韩av最新在线观看| 同产精品九九九| 99re热这里只有精品免费视频| 99精品国产在热久久| 精品国产一区二区三区| 欧美男女视频| 538在线视频| av中文天堂在线| 超碰在线一区二区三区| jizzjizzxxxx| 亚洲一区三区在线观看| 91传媒免费看| 国产精品国产三级国产专播精品人| 中文字幕av一区二区| 日韩欧美国产综合| 欧美伊人久久久久久久久影院| 中文字幕一区二区三区在线播放| 国产在线视频一区二区三区| 亚洲综合五月| 亚欧洲精品视频在线观看| 99在线播放| caoporn国产精品免费视频| 国产.com| 日韩一级免费片| www.国产区|