自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

字節(jié)一次面試,被二叉樹(shù)的層序遍歷捏爆了!

開(kāi)發(fā) 前端
在數(shù)據(jù)結(jié)構(gòu)與算法中,二叉樹(shù)無(wú)論是考研、筆試都是非常高頻的考點(diǎn)內(nèi)容,在二叉樹(shù)中,二叉樹(shù)的遍歷又是非常重要的知識(shí)點(diǎn),有個(gè)小老弟說(shuō)他字節(jié)面試時(shí)候二叉樹(shù)之字形打印緊張沒(méi)寫(xiě)出來(lái),力扣原題自己還寫(xiě)過(guò)很懊惱,我也回想起自己剛學(xué)習(xí)時(shí)候那段"混亂的"斗爭(zhēng),今天給大家講講二叉樹(shù)的層序遍歷。

[[423620]]

前言

大家好,我是bigsai。

在數(shù)據(jù)結(jié)構(gòu)與算法中,二叉樹(shù)無(wú)論是考研、筆試都是非常高頻的考點(diǎn)內(nèi)容,在二叉樹(shù)中,二叉樹(shù)的遍歷又是非常重要的知識(shí)點(diǎn),有個(gè)小老弟說(shuō)他字節(jié)面試時(shí)候二叉樹(shù)之字形打印緊張沒(méi)寫(xiě)出來(lái),力扣原題自己還寫(xiě)過(guò)很懊惱,我也回想起自己剛學(xué)習(xí)時(shí)候那段"混亂的"斗爭(zhēng),今天給大家講講二叉樹(shù)的層序遍歷。

前面介紹了二叉排序樹(shù)的構(gòu)造和基本方法的實(shí)現(xiàn),遍歷也是比較重要的一環(huán),并且二叉樹(shù)的層序遍歷也是bfs的最簡(jiǎn)單情況,這里我就將二叉樹(shù)的層序遍歷以及??紗?wèn)題給大家分享一下。

在了解二叉樹(shù)的遍歷之前,需要具備數(shù)據(jù)結(jié)構(gòu)與算法有隊(duì)列、遞歸、棧、二叉樹(shù),這些內(nèi)容咱們前面都有講過(guò),有這方面知識(shí)欠缺的同學(xué)可以往前翻一翻看一看!

層序遍歷

層序遍歷,聽(tīng)名字也知道是按層遍歷。一個(gè)節(jié)點(diǎn)有左右節(jié)點(diǎn),按層處理就是當(dāng)前層兄弟節(jié)點(diǎn)的優(yōu)先級(jí)要大于子節(jié)點(diǎn)處理的優(yōu)先級(jí),所以就是要將子節(jié)點(diǎn)放到后面處理,這就適合隊(duì)列這個(gè)數(shù)據(jù)結(jié)構(gòu)用來(lái)存儲(chǔ)。

對(duì)于隊(duì)列,先進(jìn)先出。從root節(jié)點(diǎn)push到隊(duì)列,那么隊(duì)列中先出來(lái)的順序是第二層的左右(假設(shè)都有),第二層每個(gè)節(jié)點(diǎn)執(zhí)行的時(shí)候按照左右順序添加到隊(duì)列,第三層的節(jié)點(diǎn)就會(huì)有序的放到最后面……按照這樣的規(guī)則就能得到一個(gè)層序遍歷的順序。

實(shí)現(xiàn)的代碼也很容易理解:

  1. public int[] levelOrder(TreeNode root) { 
  2.         int arr[]=new int[10000]; 
  3.         int index=0; 
  4.         Queue<TreeNode>queue=new ArrayDeque<>(); 
  5.         if(root!=null
  6.             queue.add(root); 
  7.         while (!queue.isEmpty()){ 
  8.             TreeNode node=queue.poll(); 
  9.             arr[index++]= node.val; 
  10.             if(node.left!=null
  11.                 queue.add(node.left); 
  12.             if(node.right!=null
  13.                 queue.add(node.right); 
  14.  
  15.         } 
  16.         return Arrays.copyOf(arr,index); 
  17.     } 

分層存儲(chǔ)

但是在具體筆試他可能要求你分層存儲(chǔ),例如力扣的102二叉樹(shù)的層序遍歷,要求返回一個(gè)List>類(lèi)型。

這種相比上面一個(gè)多了一層邏輯就是每一層數(shù)據(jù)放到一塊,這個(gè)也很容易,最好想到的就是兩個(gè)隊(duì)列(容器)一層一層遍歷存儲(chǔ),然后交替,但是兩個(gè)隊(duì)列(容器)的寫(xiě)法常常會(huì)被面試官嫌棄,很多面試官讓你想想怎么不用兩個(gè)容器實(shí)現(xiàn)?

不用雙隊(duì)列去枚舉結(jié)果也很容易,重要的就是先記錄隊(duì)列大小size(當(dāng)前層節(jié)點(diǎn)數(shù)量),然后執(zhí)行size次數(shù)的枚舉即可,具體代碼為:

  1. public List<List<Integer>> levelOrder(TreeNode root) { 
  2.   List<List<Integer>>list=new ArrayList<List<Integer>>(); 
  3.   if(root==null)return list; 
  4.   Queue<TreeNode>q1=new ArrayDeque<TreeNode>(); 
  5.   q1.add(root); 
  6.   while (!q1.isEmpty()) { 
  7.     int size=q1.size(); 
  8.     List<Integer>value=new ArrayList<Integer>(); 
  9.     for(int i=0;i<size;i++) 
  10.     { 
  11.       TreeNode pNode=q1.poll(); 
  12.       if(pNode.left!=null
  13.         q1.add(pNode.left); 
  14.       if(pNode.right!=null
  15.         q1.add(pNode.right); 
  16.       value.add(pNode.val); 
  17.     } 
  18.     list.add(value); 
  19.   } 
  20.   return list; 

之字形(鋸齒形)打印

除了這個(gè)直接層序遍歷,二叉樹(shù)還有很高頻的就是之字形遍歷,例如劍指offer32和力扣103 二叉樹(shù)的鋸齒形層序遍歷,它的題目要求為:

請(qǐng)實(shí)現(xiàn)一個(gè)函數(shù)按照之字形順序打印二叉樹(shù),即第一行按照從左到右的順序打印,第二層按照從右到左的順序打印,第三行再按照從左到右的順序打印,其他行以此類(lèi)推。

這道題雖然不是難題,但是有點(diǎn)繞,本來(lái)隊(duì)列這玩意我們就要大腦想一下什么順序,又出來(lái)一個(gè)之字形(鋸齒形狀),屬實(shí)增加的思維邏輯,有不少小伙伴反映當(dāng)時(shí)面試官讓手撕這道題,自己以前明明寫(xiě)過(guò),但是太緊張自己給自己繞進(jìn)去了!

其實(shí)這個(gè)問(wèn)題也很容易轉(zhuǎn)化,因?yàn)橹抵皇谴鎯?chǔ),我們按照老樣子去進(jìn)行層序遍歷,只不過(guò)在遍歷時(shí)候通過(guò)當(dāng)前層奇偶數(shù)來(lái)給它判斷是從左往右存儲(chǔ)到結(jié)果中還是從右往左放到結(jié)果中。當(dāng)然,判斷奇數(shù)偶數(shù)也很容易,可以用變量,也可以用結(jié)果List的size()都可。

個(gè)人實(shí)現(xiàn)的一個(gè)樸素代碼為:

  1. public List<List<Integer>> levelOrder(TreeNode root) { 
  2.   List<List<Integer>> value=new ArrayList<>();//存儲(chǔ)到的最終結(jié)果 
  3.   if(root==null
  4.     return value; 
  5.   int index=0;//判斷 
  6.   Queue<TreeNode>queue=new ArrayDeque<>(); 
  7.   queue.add(root); 
  8.   while (!queue.isEmpty()){ 
  9.     List<Integer>va=new ArrayList<>();//臨時(shí) 用于存儲(chǔ)到value中 
  10.     int len=queue.size();//當(dāng)前層的數(shù)量 
  11.     for(int i=0;i<len;i++){ 
  12.       TreeNode node=queue.poll(); 
  13.       if(index%2==0) 
  14.         va.add(node.val); 
  15.       else 
  16.         va.add(0,node.val); 
  17.       if(node.left!=null
  18.         queue.add(node.left); 
  19.       if(node.right!=null
  20.         queue.add(node.right); 
  21.     } 
  22.     value.add(va); 
  23.     index++; 
  24.   } 
  25.   return value; 

上面實(shí)現(xiàn)代碼也僅使用一個(gè)隊(duì)列,不過(guò)這個(gè)問(wèn)題可能有很多更巧妙的解法需要大家自己去挖掘。

結(jié)語(yǔ)

二叉樹(shù)的層序遍歷是二叉樹(shù)內(nèi)容中較為簡(jiǎn)單的內(nèi)容,但是層序遍歷尤其是之字形遍歷(鋸齒形遍歷)出現(xiàn)的頻率真的太高了,并且最好是掌握比較好的方法不要顯得太臃腫。

不過(guò)在實(shí)際遇到問(wèn)題時(shí)候,能AC是第一位,然后才是精簡(jiǎn)的邏輯和騷氣的代碼,總結(jié)一下就是隊(duì)列實(shí)現(xiàn)層序,巧用size()實(shí)現(xiàn)一個(gè)容器枚舉,奇偶判斷實(shí)現(xiàn)之字形(鋸齒形)遍歷!也還算easy!

二叉樹(shù)層序遍歷變種問(wèn)題不多,掌握上面三個(gè)問(wèn)題基本就夠了,而二叉樹(shù)的前序、中序、后序遍歷(遞歸非遞歸)考察非常多,后面會(huì)給大家加快梳理總結(jié),敬請(qǐng)期待!

 

責(zé)任編輯:武曉燕 來(lái)源: bigsai
相關(guān)推薦

2020-04-27 07:05:58

二叉樹(shù)左子樹(shù)右子樹(shù)

2022-10-26 23:58:02

二叉樹(shù)數(shù)組算法

2021-04-20 08:37:14

數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)樹(shù)

2023-05-08 15:57:16

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)

2021-09-15 07:56:32

二叉樹(shù)層次遍歷

2021-08-17 11:32:33

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)算法

2021-01-13 10:03:36

二叉樹(shù)層序遍歷層次遍歷

2009-08-11 13:29:57

C#二叉樹(shù)遍歷

2021-09-15 07:40:50

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)算法

2021-03-22 08:23:29

LeetCode二叉樹(shù)節(jié)點(diǎn)

2021-05-06 17:46:30

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)

2021-04-19 07:47:42

數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)Tree

2021-04-28 20:12:27

數(shù)據(jù)結(jié)構(gòu)創(chuàng)建

2021-07-13 11:32:41

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)算法

2024-01-23 12:54:00

C++編程語(yǔ)言代碼

2021-07-16 08:57:31

迭代遍歷二叉樹(shù)

2021-03-17 08:19:22

二叉樹(shù)LeetCode樹(shù)

2013-07-15 16:35:55

二叉樹(shù)迭代器

2021-11-29 10:40:58

二叉樹(shù)鏡像節(jié)點(diǎn)

2021-08-27 11:36:44

二叉樹(shù)回溯節(jié)點(diǎn)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)