1. 程式人生 > >二叉樹的遞歸遍歷與非遞歸遍歷-javascript

二叉樹的遞歸遍歷與非遞歸遍歷-javascript

fun 遞歸 gen ever 一個棧 順序 clas nbsp 先序



  1 function TreeNode(val) {  // 樹節點構造方式
  2     this.val = val;
  3     this.left = null;
  4     this.right = null;
  5 }
  6 
  7 function generateTree() {
  8     let root = new TreeNode(10);
  9     let left1 = new TreeNode(5);
 10     let left2 = new TreeNode(4);
 11     let left3 = new TreeNode(7);
12 let right1 = new TreeNode(12); 13 let right2 = new TreeNode(11); 14 let right3 = new TreeNode(15); 15 let right4 = new TreeNode(13); 16 root.left = left1; 17 left1.left = left2; 18 left1.right = left3; 19 root.right = right1; 20 right1.left = right2; 21
right1.right = right3; 22 right3.left = right4; 23 return root; 24 } 25 26 function visit(node) { // 遍歷方式-打印出來 27 console.log(node.val); 28 } 29 30 // 遞歸方式 31 // 前(先)序遍歷遞歸方式 32 function DLR_recursion(root) { 33 root && visit(root); 34 root.left && DLR_recursion(root.left);
35 root.right && DLR_recursion(root.right); 36 } 37 38 // 中序遍歷遞歸方式 39 function LDR_recursion(root) { 40 root.left && LDR_recursion(root.left); 41 root && visit(root); 42 root.right && LDR_recursion(root.right); 43 } 44 45 // 後序遍歷遞歸方式 46 function RDL_recursion(root) { 47 root.left && RDL_recursion(root.left); 48 root.right && RDL_recursion(root.right); 49 root && visit(root); 50 } 51 52 // 非遞歸方式 53 // 前(先)序遍歷非遞歸方式 54 function DLR(root) { 55 let arr = []; // 維護一個棧 56 root && arr.push(root); 57 while (arr.length !== 0) { 58 let temp = arr.pop(); 59 visit(temp); 60 if (temp.right !== null) { // 這裏入棧順序是先右後左,這樣由於先進後出,所以符合右子樹後出,為先序遍歷 61 arr.push(temp.right); 62 } 63 if (temp.left !== null) { 64 arr.push(temp.left); 65 } 66 } 67 } 68 69 // 中序非遞歸遍歷 70 function LDR(root) { 71 let arr = []; 72 while (true) { 73 while (root !== null) { 74 arr.push(root); 75 root = root.left; 76 } 77 // 循環的結束條件是數組長度為0,遍歷完成 78 if (arr.length === 0) { 79 break; 80 } 81 let temp = arr.pop(); 82 visit(temp); // 訪問左子樹的根節點 83 root = temp.right; // 左子樹的右子節點 84 } 85 } 86 87 // 後序非遞歸遍歷(與前序遍歷相反) 88 function RDL(root) { 89 let arr = [], res = []; 90 root && arr.push(root); 91 while (arr.length !== 0) { 92 let temp = arr.pop(); 93 res.push(temp); 94 if (temp.left !== null) { 95 arr.push(temp.left); 96 } 97 if (temp.right !== null) { 98 arr.push(temp.right); 99 } 100 } 101 res.reverse(); 102 res.forEach(item => visit(item)); 103 } 104 105 106 function run() { 107 let tree = generateTree(); 108 console.log("前(先)序遞歸遍歷", DLR_recursion(tree)); 109 console.log("前(先)序遞歸遍歷", DLR(tree)); 110 111 console.log("中序遞歸遍歷", LDR_recursion(tree)); 112 console.log("中序非遞歸遍歷", LDR(tree)); 113 114 console.log("後序遞歸遍歷", RDL_recursion(tree)); 115 console.log("後序非遞歸遍歷", RDL(tree)); 116 117 } 118 119 run();

結果輸出:
前(先)序遞歸遍歷:10,5,4,7,12,11,15,13
前(先)序非遞歸遍歷:10,5,4,7,12,11,15,13
中序遞歸遍歷:4,5,7,10,11,12,13,15
中序非遞歸遍歷:4,5,7,1011,12,13,15
後序遞歸遍歷:4,7,5,1113,15,12,10
後序非遞歸遍歷:4,7,5,1113,15,12,10
 

二叉樹的遞歸遍歷與非遞歸遍歷-javascript