Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
Today we’re going to look at tree traversal, recursive and non-recursive
The structure of the tree
function TreeNode(val, left, right) {
this.val = (val===undefined ? 0 : val)
this.left = (left===undefined ? null : left)
this.right = (right===undefined ? null : right)
}
Copy the code
Tree traversal
Depth-first traversal DFS (recursive)
function DFS(root) {
if (root === null) return;
DFS(root.left);
DFS(root.right);
}
Copy the code
Depth-first traversal DFS (stack)
I don’t have to do this recursively, but you can draw a picture on a piece of paper, and I’ll do a couple more pictures when I have time
function DFS(root) {
const stack = [];
stack.push(root);
while (stack.length > 0) {
root = stack.pop();
if (root.right) stack.push(root.right);
if(root.left) stack.push(root.left); }}Copy the code
Breadth-first traversal of BFS (queue)
function BFS(root){
const queue = [];
queue.unshift(root);
while(queue.length > 0) {
root = queue.pop();
if(root.left) queue.unshift(root.left);
if(root.right) queue.unshift(root.right); }}Copy the code
Middle order traversal of binary trees
Middle-order traversal traverses the left subtree, then visits the root node, and then traverses the right subtree.
Left-center-right
Leetcode-cn.com/problems/bi…
144. Antecedent traversal of binary trees
Center-left-right
Leetcode-cn.com/problems/bi…
145. Back-order traversal of binary trees
Left-right-middle leetcode-cn.com/problems/bi…
Anterior: root left and right; Middle sequence: left root right; Postsequence: left and right roots; Middle order is often used to obtain increasing ordered sequences in binary search numbers. Postsequence can be used in mathematics suffix notation, combined with stack processing expression, each encountered an operator, you can pop two elements on the top of the stack, calculate and return the result to the stack;
[Solution 1] Recursive DFS
Using recursion, the writing method of the three traversal methods is relatively uniform
/ * * *@param {TreeNode} root
* @return {number[]}* /
function inorderTraversal(root) {
// Define a result array to hold the values of the nodes traversed
const result = [];
// Define a recursive function
function inorder(root) {
// exit recursively until the node is empty
if (root === null) return;
//
// Recursive call passed to the left child of the root node
inorder(root.left);
// select * from left to right;
// Put the value of the root node into the Result array
result.push(root.val);
// Call recursively, passing in the right child of the root node
inorder(root.right);
}
// Execute the recursive function to represent the current traversal to root
inorder(root);
return result;
}
Copy the code
[Solution 2] Non-recursive iteration method – stack
Non-recursively, use a stack
In the sequence traversal
A stack and loop to simulate recursive operations
Iterate through the tree and stack using a while loop
function inorderTraversal(root) {
const result = []
const stack = []
// Walk through the tree, end: node is empty and stack is empty
while(root || stack.length > 0) {// Iterate over the root node and all its left children
while(root){
stack.push(root)
root = root.left
}
// The left child traverses the stack and the top element is off the stack
root = stack.pop()
// * * * * * * * * * * * *
result.push(root.val)
// Point to the right child, if there is no null, the next loop will unstack an element
root = root.right
}
return result
}
Copy the code
The former sequence traversal
var preorderTraversal = function(root) {
const result = []
const stack = []
while(root || stack.length > 0) {while(root){
// 【 foreword: middle - left - right 】
result.push(root.val)
stack.push(root)
root = root.left
}
root = stack.pop()
root = root.right
}
return result
};
Copy the code
Post-order traversal (heavy and difficult points)
var postorderTraversal = function(root) {
const result = []
const stack = []
// to mark the node
let prev = null
while(root || stack.length > 0) {while(root){
// Walk through the node left child to the end
stack.push(root)
root = root.left
}
// push a node off the stack to perform the following operations
root = stack.pop()
// 【后 置 : left - right - middle 】
// If there is a right child, and the right child is not marked, push the right child to the stack, while traversing the right child
if(root.right ! = =null&& root.right ! == prev){// The pointer moves to the right, and then loops [right]
stack.push(root)
root = root.right
}else {
// At this point, there is no right child, or there is a right child, but is marked [middle]
// Store the value of the node into the result array
result.push(root.val)
// The saved nodes are marked
prev = root
// The node is cleared
root = null}}return result
};
Copy the code
【 句 型 3 】Morris is the word in the word “Morris”
Convert a binary tree into a linked list, where each node can have only the right child
function inorderTraversal(root) {
const result = [];
let predecessor = null;
while(root ! = =null) {
if (root.left) {
The predecessor node is the current root node that goes one step to the left and then continues to go right until it can no longer go
predecessor = root.left;
while(predecessor.right && predecessor.right ! == root) { predecessor = predecessor.right; }// Let the predecessor's right pointer point to root to continue traversing the left subtree
if(! predecessor.right) { predecessor.right = root; root = root.left; }else {
// The left subtree has been accessed and we need to disconnect the link
result.push(root.val);
predecessor.right = null; root = root.right; }}else {
// If there is no left child, access the right child directlyresult.push(root.val); root = root.right; }}return result;
}
Copy the code