1.はじめに
二分木には、前順、順順、後順の 3 つの走査方法があります。关注根的位置,便于理解先中后
.
1️⃣ 先行トラバーサル【ルート左右】
- ルート ノードにアクセスします。
- 左の部分木を再帰的に順番にトラバースします。
- preorder 再帰を使用して、右側のサブツリーをトラバースします。
注: 各ノードの分岐は、「再帰呼び出し」を反映して、上記のアクセス順序に従います。
2️⃣Inorder Traversal [左ルート右]
- 左のサブツリーをトラバースするには、inorder を使用します。
- ルート ノードにアクセスします。
- 正しいサブツリーを順番にトラバースします。
3️⃣ポストオーダー トラバーサル: [左右のルート]
- 後置再帰を使用して、左側のサブツリーをトラバースします。
- ポストオーダー再帰を使用して、正しいサブツリーをトラバースします。
- ルート ノードにアクセスします。
public class TreeNode {
public TreeNode left;
public TreeNode right;
public Integer val;
public TreeNode(int val) {
this.val = val;
}
}
第二に、事前注文トラバーサル
public class PreorderTraversal {
public List<Integer> preorder(TreeNode root){
ArrayList<Integer> res = new ArrayList<>();
accessTree(root,res);
return res;
}
private void accessTree(TreeNode root, ArrayList<Integer> res) {
if(root==null){
return;
}
res.add(root.val);
accessTree(root.left,res);
accessTree(root.right,res);
}
public List<Integer> preorder02(TreeNode root){
ArrayList<Integer> res = new ArrayList<>();
Deque<TreeNode> stack=new LinkedList<>();
while(root!=null||!stack.isEmpty()){
while(root!=null){
res.add(root.val);
stack.push(root);
root=root.left;
}
root=stack.pop();
root=root.right;
}
return res;
}
}
3. 順序通りのトラバーサル
public class InorderTraversal {
public List<Integer> inOrder(TreeNode root) {
ArrayList<Integer> res = new ArrayList<>();
accessTree(root, res);
return res;
}
private void accessTree(TreeNode root, ArrayList<Integer> res) {
if (root == null) {
return;
}
accessTree(root.left, res);
res.add(root.val);
accessTree(root.right, res);
}
public List<Integer> inOrder02(TreeNode root) {
ArrayList<Integer> res = new ArrayList<>();
Deque<TreeNode> stack = new LinkedList<>();
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
res.add(root.val);
root = root.right;
}
return res;
}
}
4 番目、ポストオーダー トラバーサル
public class PostorderTraversal {
public List<Integer> postorder(TreeNode root) {
ArrayList<Integer> res = new ArrayList<>();
accessTree(root, res);
return res;
}
private void accessTree(TreeNode root, ArrayList<Integer> res) {
if (root == null) {
return;
}
accessTree(root.left, res);
accessTree(root.right, res);
res.add(root.val);
}
public List<Integer> postorder02(TreeNode root) {
ArrayList<Integer> res = new ArrayList<>();
Deque<TreeNode> stack = new LinkedList<>();
TreeNode preAccess = null;
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
if (root.right == null || root.right == preAccess) {
res.add(root.val);
preAccess = root;
root = null;
} else {
stack.push(root);
root = root.right;
}
}
return res;
}
}
5. テスト
public static void main(String[] args) {
TreeNode root = new TreeNode(0);
TreeNode node1 = new TreeNode(1);
TreeNode node2 = new TreeNode(2);
TreeNode node3 = new TreeNode(3);
TreeNode node4 = new TreeNode(4);
TreeNode node5 = new TreeNode(5);
root.left = node1;
root.right = node2;
node1.left = node3;
node1.right = node4;
node2.left = node5;
//先序遍历【中左右】[0, 1, 3, 4, 2, 5]
PreorderTraversal preorder = new PreorderTraversal();
List<Integer> preorderRes = preorder.preorder(root);
System.out.println(Arrays.toString(preorderRes.toArray()));
//中序遍历【左中右】[3, 1, 4, 0, 5, 2]
InorderTraversal inorder = new InorderTraversal();
List<Integer> inorderRes = inorder.inOrder(root);
System.out.println(Arrays.toString(inorderRes.toArray()));
//后序遍历【左右中】[3, 4, 1, 5, 2, 0]
PostorderTraversal postorder = new PostorderTraversal();
List<Integer> postorderRes = postorder.postorder(root);
System.out.println(Arrays.toString(postorderRes.toArray()));
}