算法:二叉樹的層次遍歷(遞歸實現+非遞歸實現,lua)


二叉樹知識參考:深入學習二叉樹(一) 二叉樹基礎

遞歸實現層次遍歷算法參考:【面經】用遞歸方法對二叉樹進行層次遍歷 && 二叉樹深度

 

上面第一篇基礎寫得不錯,不了解二叉樹的值得一看。

 

遞歸來實現二叉樹的層次遍歷。lua實現

先上代碼:

 

function FindTree(tree, callback)
   local function Find(tree, level)
       if(tree == nil or level <= 0) then 
         return false;
       end
       if (level == 1) then 
         if callback then
            callback(tree.data);
         end
         return true;
       end

       local has_left = Find(tree.left, level - 1);
       local has_right = Find(tree.right, level - 1);

       return has_left or has_right;
   end

   local level = 1;
   while Find(tree, level, callback) do
       level = level + 1;
   end
end

 

測試代碼:

 

a={};
a.data = "a"

b, c = {}, {}
b.data = "b"
c.data = "c"
a.left = b
a.right = c

d, e, f, g = {}, {}, {}, {}
d.data = "d"
e.data = "e"
f.data = "f"
g.data = "g"
b.left = d
b.right = e
c.left = f
c.right = g

h, i, j = {}, {}, {}
h.data = "h"
i.data = "i"
j.data = "j"
d.left = h
d.right = i
e.left = j


local  list = {}
FindTree(a, function(data)
   table.insert(list, data)
end)

print(table.concat(list, ", "))

 

 

結果:

 

基本思路 (下面的a是測試樹的根結點):

 

每步,都是一次從根到當前層級的自上而下的一次遍歷,從上到下找到第1層a,  從上到下找到第2層b,c,從上到下找到第3層d,e,f,g

詳細步驟:

1,FindTree(a, 1) : 如果此樹深度大於等於1,a結點的data通過回調傳回,函數返回true , while循環繼續;如果深度為0,a==null,直接返回false,while循環結束。

2,FindTree(a, 2):如果此樹深度大於等於2,傳回a的子結點(上圖b位置,或c位置,或bc位置)的data,返回true , while循環繼續;如果深度小於2,返回false,while循環結束。

  這里就比較復雜了,需要對函數遞歸有一定的了解。執行到 has_left = FindTree(tree.left, level - 1); ,現場被保留(后續代碼暫時不執行),程序再次進入到FindTree函數(即執行has_left = FindTree(b, 1)),當a有左子節點時,傳回a的左子節點的data,返回true,即 has_left =true; 否則 has_left = false;  然后執行到has_right = FindTree(tree.right, level - 1); 同理,如果有右子節點,傳回a的右子節點的data,返回true,has_right=true; 否則 has_right= false。如果a有左子節點或右子節點(或都有),整個函數返回true,while循環繼續;如果a沒有左結點和右結點,即深度小於2,has_left or has_right = false ,while循環結束。

3,FindTree(a, 3):如果此樹深度大於等於3,傳回a的深度為3的子結點(上圖d, e, f, g的各位置隨意組合)的data,返回true , while循環繼續;如果深度小於2,返回false,while循環結束。

  同理,執行到 has_left = FindTree(tree.left, level - 1); 時,現場保留,直到has_left = FindTree(tree.left.left, level - 1 - 1); 即has_left = FindTree(d, 1),如果d結點不存在,返回false,has_left = false; 如果存在,打印d結點的data,返回true,has_left = true; e, f, g各個位置 的檢測同理。

4,…… , n - 1,

n,FindTree(a, n): 深度小於n (此樹深度為n-1),返回false,while循環結束。

 

遞歸來實現二叉樹的層次遍歷。lua實現

先上代碼:

function FindTree2(tree, callback)
   local  nodeList = {tree}
   while #nodeList > 0 do
      local  tempList = {}
      for i, v in ipairs(nodeList) do 
         if callback then
            callback(v.data)
         end
         table.insert(tempList, v.left)
         table.insert(tempList, v.right)
      end
      nodeList = tempList;
   end
end

測試代碼:如上

測試如果:如上

基本思路:從上到下,每一層從左到右依次遍歷。把每一層子節點存放在一個列表,直到這個列表為空,則遍歷完成。

這個方式比較直觀,直接看一下上面的圖和代碼,很容易理解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM