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

算法: 如何優雅的使用Javascript遞歸畫一棵結構樹

開發 前端 算法
簡單的說,遞歸就是函數自己調用自己,它做為一種算法在程序設計語言中廣泛應用。其核心思想是把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解。一般來說,遞歸需要有邊界條件、遞歸前進階段和遞歸返回階段。當邊界條件不滿足時,遞歸前進;當邊界條件滿足時,遞歸返回。

[[376839]]

遞歸和尾遞歸

簡單的說,遞歸就是函數自己調用自己,它做為一種算法在程序設計語言中廣泛應用。其核心思想是把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解。一般來說,遞歸需要有邊界條件、遞歸前進階段和遞歸返回階段。當邊界條件不滿足時,遞歸前進;當邊界條件滿足時,遞歸返回。

但是作為一個合格的程序員,我們也因該知道,遞歸算法相對常用的算法如普通循環等,運行效率較低。因此,應該盡量避免使用遞歸,除非沒有更好的算法或者某種特定情況,遞歸更為適合的時候。在遞歸調用的過程當中系統為每一層的返回點、局部量等開辟了棧來存儲,遞歸次數過多容易造成棧溢出等。

這個時候,我們就需要用到尾遞歸,即一個函數中所有遞歸形式的調用都出現在函數的末尾,對于尾遞歸來說,由于只存在一個調用記錄,所以永遠不會發生"棧溢出"錯誤。

 

  1. function factorial(n) { 
  2.   if (n === 1) return 1; 
  3.   return n * factorial(n - 1); 
  4.  
  5. factorial(5) // 120 

 

最多需要保存n個調用棧,復雜度 O(n),如果我們使用尾遞歸:

  1. function factorial(n, total = 1) { 
  2.   if (n === 1) return total; 
  3.   return factorial(n - 1, n * total); 
  4.  
  5. factorial(5) // 120 

此時只需要保存一個調用棧,復雜度 O(1) 。通過這個案例,你是否已經慢慢理解其精髓了呢?接下來我將介紹幾個常用的遞歸應用的案例,并在其后實現本文標題剖出的樹的實現。

遞歸的常用應用案例

1. 數組求和

對于已知數組arr,求arr各項之和。

 

  1. function sumArray(arr, total) { 
  2.     if(arr.length === 1) { 
  3.         return total 
  4.     } 
  5.     return sum(arr, total + arr.pop()) 
  6.  
  7. let arr = [1,2,3,4]; 
  8. sumArray(arr, arr[1]) // 10 

該方法給函數傳遞一個數組參數和初始值,也就是數組的第一項,通過迭代來實現數組求和。

2. 斐波那且數列

斐波那契數列(Fibonacci sequence),又稱黃金分割數列,指的是這樣一個數列:1、1、2、3、5、8、13、21、34、……在數學上,斐波那契數列以如下被以遞推的方法定義:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)在現代物理、準晶體結構、化學等領域,斐波納契數列都有直接的應用。接下來我們用js實現一個求第n個斐波那契數的方法:

 

  1. // 斐波那契數列 
  2. function factorial1 (n) { 
  3.     if(n <= 2){ 
  4.         return 1 
  5.     } 
  6.     return factorial1(n-1) + factorial1(n-2) 
  7.  
  8. // 尾遞歸優化后 
  9. function factorial2 (n, start = 1, total = 1) { 
  10.     if(n <= 2){ 
  11.         return total 
  12.     } 
  13.     return factorial2 (n -1, total, total + start) 

由尾遞歸優化后的函數可以知道,每一次調用函數自身,都會將更新后的初始值和最終的結果傳遞進去,通過回溯來求得最終的結果。

3. 階乘

階乘在上文以提到過,如想回顧,請向上翻閱。

4. 省市級聯多級聯動

省市級聯多級聯動的方法本質是生成結構化的數據結構,在element或antd中都有對應的實現,這里就不做過多介紹了。

5. 深拷貝

深拷貝的例子大家也已經司空見慣了,這里只給出一個簡單的實現思路:

 

  1. function clone(target) { 
  2.    if (typeof target === 'object') { 
  3.        let cloneTarget = Array.isArray(target) ? [] : {}; 
  4.        for (const key in target) { 
  5.            cloneTarget[key] = clone(target[key]); 
  6.        } 
  7.        return cloneTarget; 
  8.    } else { 
  9.        return target; 
  10.    } 
  11. }; 

6. 爬梯問題

一共有n個臺階,每次只能走一個或兩個臺階,問要走完這個臺階,一共有多少種走法。

 

  1. n =1; result = 1  --> 1 
  2. n =2; result = 2  --> 11 2 
  3. n =3; result = 3  --> 111 12 21 
  4. ... 
  5. 如果第一步走1個臺階,由以上規律可以發現剩下的臺階有n-1種走法; 
  6. 如果第一步走2個臺階,由以上規律可以發現剩下的臺階有n-2種走法; 
  7. 則一共有fn(n-1) + fn(n-2) 種走法 
  8. function steps(n) { 
  9.     if(n <= 1) { 
  10.         return 1 
  11.     } 
  12.     return steps(n-1) + steps(n-2) 

7. 對象數據格式化

這道題是本人曾經面試阿里的一道筆試題,問題是如果服務器返回了嵌套的對象,對象鍵名大小寫不確定,如果統一讓鍵名小寫。

 

  1. let obj = { 
  2.     a: '1'
  3.     b: { 
  4.         c: '2'
  5.         D: { 
  6.             E: '3' 
  7.         } 
  8.     } 
  9. 轉化為如下: 
  10. let obj = { 
  11.     a: '1'
  12.     b: { 
  13.         c: '2'
  14.         d: { 
  15.             e: '3' 
  16.         } 
  17.     } 
  18.  
  19. // 代碼實現 
  20. function keysLower(obj) { 
  21.     let reg = new RegExp("([A-Z]+)""g"); 
  22.     for (let key in obj) { 
  23.         if (obj.hasOwnProperty(key)) { 
  24.             let temp = obj[key]; 
  25.             if (reg.test(key.toString())) { 
  26.                 // 將修改后的屬性名重新賦值給temp,并在對象obj內添加一個轉換后的屬性 
  27.                 temp = obj[key.replace(reg, function (result) { 
  28.                     return result.toLowerCase() 
  29.                 })] = obj[key]; 
  30.                 // 將之前大寫的鍵屬性刪除 
  31.                 delete obj[key]; 
  32.             } 
  33.             // 如果屬性是對象或者數組,重新執行函數 
  34.             if (typeof temp === 'object' || Object.prototype.toString.call(temp) === '[object Array]') { 
  35.                 keysLower(temp); 
  36.             } 
  37.         } 
  38.     } 
  39.     return obj; 
  40. }; 

具體過程和思路在代碼中已經寫出了注釋,感興趣可以自己研究一下。

8. 遍歷目錄/刪除目錄

我們這里使用node來實現刪除一個目錄,用現有的node API確實有刪除目錄的功能,但是目錄下如果有文件或者子目錄,fs.rmdir && fs.rmdirSync 是不能將其刪除的,所以要先刪除目錄下的文件,最后再刪除文件夾。

 

  1. function deleteFolder(path) { 
  2.     var files = []; 
  3.     if(fs.existsSync(path)) { // 如果目錄存在 
  4.         files = fs.readdirSync(path); 
  5.         files.forEach(function(file,index){ 
  6.             var curPath = path + "/" + file; 
  7.             if(fs.statSync(curPath).isDirectory()) { // 如果是目錄,則遞歸 
  8.                 deleteFolder(curPath); 
  9.             } else { // 刪除文件 
  10.                 fs.unlinkSync(curPath); 
  11.             } 
  12.         }); 
  13.         fs.rmdirSync(path); 
  14.     } 

9. 繪制分形圖形

通過遞歸,我們可以在圖形學上有更大的自由度,但是請記住,并不是最好的選擇。


我們可以借助一些工具和遞歸的思想,實現如上的分形圖案。

 10. 扁平化數組Flat

數組拍平實際上就是把一個嵌套的數組,展開成一個數組,如下案例:

 

  1. let a = [1,2,3, [1,2,3, [1,2,3]]] 
  2. // 變成 
  3. let a = [1,2,3,1,2,3,1,2,3] 
  4. // 具體實現 
  5. function flat(arr = [], result = []) { 
  6.     arr.forEach(v => { 
  7.         if(Array.isArray(v)) { 
  8.             result = result.concat(flat(v, [])) 
  9.         }else { 
  10.             result.push(v) 
  11.         } 
  12.     }) 
  13.     return result 
  14.  
  15. flat(a) 

當然這只是筆者實現的一種方式,更多實現方式等著你去探索。

用遞歸畫一棵自定義風格的結構樹

通過上面的介紹,我想大家對遞歸及其應用已經有一個基本的概念,接下來我將一步步的帶大家用遞歸畫一棵結構樹。效果圖:

 

該圖形是根據目錄結構生成的目錄樹圖,在很多應用場景中被廣泛使用,接下來我們就來看看他的實現過程吧:

 

  1. const fs = require('fs'
  2. const path = require('path'
  3. // 遍歷目錄/生成目錄樹 
  4. function treeFolder(path, flag = '|_') { 
  5.     var files = []; 
  6.      
  7.     if(fs.existsSync(path)) { 
  8.         files = fs.readdirSync(path); 
  9.         files.forEach(function(file,index){ 
  10.             var curPath = path + "/" + file; 
  11.             if(fs.statSync(curPath).isDirectory()) { // recurse 
  12.                 // obj[file] = treeFolder(curPath, {}); 
  13.                 console.log(flag, file) 
  14.                 treeFolder(curPath, '   ' + flag) 
  15.             } else { 
  16.                 // obj['--'] = file 
  17.                 console.log(flag, file) 
  18.             } 
  19.         }) 
  20.         // return obj 
  21.     } 
  22.  
  23. treeFolder(path.resolve(__dirname, './test')) 

test為我們建的測試目錄,如下:

 

我們通過短短10幾行代碼就實現了一個生成結構樹的小應用,是不是感覺遞歸有點意思呢?在這個函數中,第一個參數是目錄的絕對路徑,第二個是標示符,標示符決定我們生成的樹枝的樣式,我們可以自定義不同的樣式。

 

責任編輯:姜華 來源: 趣談前端
相關推薦

2011-08-01 13:51:31

Web

2021-06-04 07:55:05

MySQLB+ 樹數據

2021-09-06 10:38:50

二叉搜索樹遞歸

2018-04-12 11:20:16

MySQLmybatisJava

2022-03-31 08:15:59

遞歸代碼非遞歸

2024-06-11 08:32:37

JavaScrip隨機樹UI

2021-05-21 08:31:09

數據結構二叉樹

2018-03-07 16:53:25

EBG業務技術

2014-04-04 11:14:18

JavaScriptStack遞歸

2023-12-05 07:26:21

Golang項目結構

2017-07-26 11:32:50

NETRabbitMQ系統集成

2015-11-26 10:53:45

LinuxWindowsMac OS

2021-02-24 07:46:20

數據結構二叉樹

2021-09-15 07:40:50

二叉樹數據結構算法

2024-01-15 07:42:37

Figma協同編輯算法

2017-12-12 14:26:16

數據庫PostgreSQL邏輯優化

2019-09-20 15:47:24

代碼JavaScript副作用

2023-06-16 09:08:39

ReactContextRFC

2013-10-16 15:57:39

數組二叉樹

2021-07-12 15:35:56

JavaScript代碼運算符
點贊
收藏

51CTO技術棧公眾號

国产日韩1区| 国产一级二级三级在线观看| 国产精品 欧美激情| 国产精品无码在线播放 | 5566中文字幕一区二区电影| 天堂v在线视频| 三级视频在线看| 免费日本视频一区| 久久久免费精品| 88国产精品欧美一区二区三区| 香蕉网在线视频| 乡村艳史在线观看| 欧美肥老太太性生活| 最新国产精品| 亚洲精品动漫100p| 九一精品久久久| 欧美办公室脚交xxxx| 亚洲欧洲99久久| 美女三级99| 亚洲精品国产suv一区| 日韩极品在线观看| 国内精品视频一区| 色婷婷在线视频观看| 欧美**字幕| 亚洲风情亚aⅴ在线发布| 午夜宅男在线视频| 另类专区亚洲| 午夜不卡av在线| 日本免费成人网| 一级毛片视频在线| 久久久亚洲高清| 亚洲婷婷在线视频| 国产一区高清在线| 在线观看成人黄色| 国产午夜精品一区二区三区 | 亚洲欧美视频| 欧美日韩爱爱视频| 欧美一区二区三区观看| 久久99高清| 亚洲成人久久网| 日韩欧美色视频| 中文字幕日本一区| 欧美亚洲图片小说| 99福利在线观看| 狠狠躁少妇一区二区三区| 一区二区三区四区中文字幕| 一本久久a久久精品vr综合| 黄色电影免费在线看| 26uuu另类欧美| 久草精品电影| 日本成人一区| 久久亚洲私人国产精品va媚药| 国产一区二区无遮挡| 噜噜噜久久,亚洲精品国产品| 国产91在线观看| 翡翠波斯猫1977年美国| 亚洲精品久久久久久久久久久久久久 | www.热久久| 国产成人精品免费视频网站| 亚洲mm色国产网站| 成人激情四射网| av不卡一区二区三区| 久久人人九九| 黄上黄在线观看| 国产精品素人一区二区| 在线观看日韩羞羞视频| av理论在线观看| 亚洲一区二区三区精品在线| 成年人午夜视频在线观看| 色在线免费观看| 91久久免费观看| 黄色小视频免费网站| 精品国产欧美| 亚洲国产精品久久久久秋霞蜜臀| 久久丫精品国产亚洲av不卡| 国产精品免费大片| 中文综合在线观看| 欧美丰满艳妇bbwbbw| 日韩一级精品| 日本一本a高清免费不卡| 亚洲大尺度在线观看| 久久99国产精品久久| 成人免费观看网站| 青青免费在线视频| 中文字幕高清不卡| www.日本在线视频| 成人影院入口| 91精品国产高清一区二区三区蜜臀 | 美女毛片在线观看| 亚洲国产中文字幕在线| 99精品全国免费观看视频软件| 成人444kkkk在线观看| 精品无码m3u8在线观看| 日韩精品亚洲专区| 99国精产品一二二线| 巨骚激情综合| 亚洲伦在线观看| 欧美日韩在线不卡视频| 国产精品一级在线观看| 亚洲美女av在线| 国产成人自拍网站| 蜜桃av一区| 999国产在线| 久久久久久久久亚洲精品| 亚洲精品免费电影| 国内自拍视频一区| 999久久久精品一区二区| 中文字幕亚洲自拍| 91精品国产乱码久久久张津瑜| 麻豆一区二区三| 国产在线资源一区| av在线看片| 欧美日韩一区二区在线观看视频| 黄色免费视频网站| 亚洲欧美综合| 91精品国产综合久久香蕉最新版 | 成人欧美一区二区三区小说| 日本福利视频在线| 国产精品久久久久久久久久久久久久久 | 欧美日韩成人高清| 丝袜美腿中文字幕| 精品999日本| 亚洲字幕一区二区| 日本三级在线视频| 色婷婷国产精品| 理论片大全免费理伦片| 欧美 日韩 国产 一区| 国产精品一区av| 免费在线稳定资源站| 国产后进白嫩翘臀在线观看视频| 午夜精品免费在线| 日韩久久久久久久久久久| 色琪琪久久se色| 国产精品2018| 福利成人在线观看| 一本色道久久加勒比精品| 一级黄色免费视频| 国产精品videosex极品| 亚洲综合精品伊人久久| av网站免费在线观看| 欧美精品色综合| 五月婷婷综合激情网| 日韩av不卡一区二区| 欧美精品国产精品久久久 | 国产va在线视频| 日韩欧美中文字幕制服| √天堂中文官网8在线| 久久99热99| 亚洲第一精品区| 91精品一区| 久久久精品在线| 精品噜噜噜噜久久久久久久久试看| 国产精品边吃奶边做爽| 激情国产一区| 欧美性猛交xxxx偷拍洗澡| 亚洲天堂国产视频| 欧美三级三级| 国产精品视频在线观看| 五月婷婷在线视频| 69成人精品免费视频| 内射一区二区三区| 国产精品亚洲午夜一区二区三区| 五月天激情图片| 伊人久久亚洲| 性生活三级视频| 日韩在线播放中文字幕| 在线不卡欧美| caoporn国产精品免费公开| 在线āv视频| 亚洲成人网av| 性无码专区无码| 国产日韩欧美麻豆| 伊人国产在线视频| 午夜欧美理论片| 久精品国产欧美| 99只有精品| 欧美精品在线免费| 天堂在线中文| 欧美日韩一区二区不卡| 美女毛片在线观看| 国产拍欧美日韩视频二区| 欧美日韩精品免费观看| 色8久久影院午夜场| 亚洲欧美日韩精品久久亚洲区 | 免费在线不卡av| 国产人妖乱国产精品人妖| 亚洲国产日韩欧美在线观看| 午夜精品剧场| 青青草国产精品| 日韩激情欧美| 久青草免费视频| 蜜桃91丨九色丨蝌蚪91桃色| 美女黄色片网站| 婷婷精品视频| 亚洲va国产va天堂va久久| 国产精品yjizz视频网| 亚洲视频电影图片偷拍一区| 国产精品视频a| 欧美视频在线免费看| 小泽玛利亚一区二区免费| 97久久超碰国产精品| 国内自拍第二页| 久久动漫亚洲| 99在线免费视频观看| 成人羞羞视频播放网站| 国内视频一区| 午夜视频一区二区在线观看| 国产精品免费看久久久香蕉| 爱草tv视频在线观看992| 北条麻妃一区二区三区中文字幕| 日韩在线免费看| 欧美成人a在线| 国产有码在线观看| 在线一区二区视频| 男女视频免费看| 亚洲黄网站在线观看| 欧美性猛交xxxx乱大交少妇| 91免费国产在线| 岛国精品一区二区三区| 国产在线播放一区三区四| 亚洲一区二区蜜桃| 国产美女诱惑一区二区| 野外做受又硬又粗又大视频√| 无需播放器亚洲| 日韩欧美在线免费观看| 男人天堂资源网| 久久麻豆一区二区| 成人在线视频免费播放| 国产高清精品在线| 男人午夜视频在线观看| 欧美aaaaa成人免费观看视频| 黄色片视频在线免费观看| 亚洲人成在线影院| 日本欧美视频在线观看| 国产一区日韩欧美| 老司机午夜免费福利视频| 亚洲成人国产| 男人天堂成人网| 91精品亚洲| 最新精品视频| 91精品一区二区三区综合| aaa免费在线观看| 国产精品久久观看| 成年人黄色在线观看| 亚洲国产精品久久久天堂 | 户外极限露出调教在线视频| 亚洲精品影视在线观看| 你懂的在线播放| 亚洲性猛交xxxxwww| 国产在线电影| 自拍偷拍亚洲欧美| 米奇777四色精品人人爽| 久久在线免费观看视频| 肉肉视频在线观看| 欧美激情一区二区三区高清视频| 丁香花在线观看完整版电影| 午夜精品三级视频福利| 惠美惠精品网| 国产啪精品视频网站| 激情视频亚洲| 国产久一道中文一区| 欧美三级电影网| 人妻熟女aⅴ一区二区三区汇编| 波多野洁衣一区| 亚洲 欧美 日韩在线| 99九九99九九九视频精品| 好吊一区二区三区视频| 久久日韩精品一区二区五区| 国产一级久久久久毛片精品| 中文字幕av一区二区三区高| 朝桐光av在线| 一区二区三区不卡视频在线观看| 豆国产97在线 | 亚洲| 欧美日韩在线免费观看| 亚洲av中文无码乱人伦在线视色| 欧美色倩网站大全免费| 成人av无码一区二区三区| 精品偷拍一区二区三区在线看| 国产美女视频一区二区三区| 国产欧美日韩一级| 国产真人无码作爱视频免费| 麻豆精品国产传媒mv男同| 国产999免费视频| 91视频免费观看| 精品少妇一区二区三区密爱| 依依成人精品视频| 久久精品国产美女| 久久精品国产大片免费观看| 97免费视频观看| 天堂成人国产精品一区| 日韩av片免费观看| 99免费精品在线观看| 国产在线免费av| 亚洲v中文字幕| 亚洲午夜激情视频| 六月丁香婷婷色狠狠久久| 欧美日韩国产综合视频在线观看 | 青青影院一区二区三区四区| 香蕉久久夜色| 久久大综合网| 日韩黄色片在线| 蜜臀国产一区二区三区在线播放| 日韩av成人网| 欧美国产激情一区二区三区蜜月| 国产精品成人久久| 欧美另类高清zo欧美| 日韩a级作爱片一二三区免费观看| 久久久999国产| 色8久久影院午夜场| 国产三级精品在线不卡| 国产精品成人av| 男人舔女人下面高潮视频| 国产成a人亚洲| 欧美性猛交xxxx乱大交少妇| 欧美性jizz18性欧美| 成人h动漫精品一区二区无码 | 免费看男女www网站入口在线| 国产精品劲爆视频| 国产96在线亚洲| 在线观看视频黄色| 日日摸夜夜添夜夜添国产精品| 少妇激情一区二区三区视频| 亚洲情趣在线观看| 亚洲天堂手机版| 中文字幕在线观看亚洲| 秋霞国产精品| 欧美日韩精品一区| 亚洲少妇自拍| 美女黄色一级视频| 亚洲自拍偷拍麻豆| 精品人妻一区二区三区浪潮在线| 久久久91精品国产一区不卡| 日韩精品第二页| 伊人久久大香线蕉午夜av| 三级一区在线视频先锋| 亚洲国产天堂av| 日韩欧美在线免费| 蜜桃视频在线入口www| 欧美亚洲午夜视频在线观看| 日韩aaa久久蜜桃av| 久久久久久久久久久99| 成人国产精品免费观看动漫| 日本少妇吞精囗交| 亚洲国产日韩欧美综合久久 | 国产精品旅馆在线| 欧美一区二区性| 高清av免费看| 亚洲色图第一区| 国产黄色片网站| 欧美精品电影免费在线观看| 国产精品主播一区二区| 久久综合九色综合欧美亚洲| 91嫩草|国产丨精品入口| 欧美一卡二卡三卡| 欧美亚洲系列| 国产美女精品久久久| 国产欧美大片| 男人舔女人下部高潮全视频| 欧美在线短视频| 免费黄色网址在线观看| 亚洲综合色激情五月| 精品电影一区| 国产精品成人一区二区三区电影毛片| 在线免费观看视频一区| 日本三级视频在线播放| 999国内精品视频在线| 日韩午夜免费视频| 国产黄色大片免费看| 91精品国产综合久久蜜臀| 免费在线看电影| 欧美精品久久| 激情综合色综合久久综合| 久久精品久久国产| 亚洲人成电影网站色…| 91成人福利社区| 国产精品裸体瑜伽视频| 欧美国产禁国产网站cc| 成人毛片在线免费观看| 国产成人极品视频| 久久久久国产| 成人网站免费观看| 欧美日韩国产小视频在线观看| 久久一卡二卡| 日韩欧美99| 夫妻av一区二区| 国产成人av免费| 欧美激情在线观看| 成人午夜av| 国产一级伦理片| 777亚洲妇女| 免费电影日韩网站| 天天想你在线观看完整版电影免费 | 日本精品久久中文字幕佐佐木| 91成人国产| 中文字幕免费视频| 欧美成人三级电影在线| 高清欧美日韩| 亚洲第一狼人社区| 亚洲成a人片77777精品| 国产精品第1页|