二叉树的先序,中序,层次遍历,递归与非递归实现

1. TreeNode的ADT

class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;

    public TreeNode(int val) {
        this.val = val;
        this.left=null;
        this.right=null;
    }
}

2. 二叉树的反序列化

//将字符串形如"1,2,3,#,#,4,5"转化为二叉树,即反序列化,#代表空节点
public TreeNode deserialize(String data) {       
        if (data == null)
            return null;
        String[] vals = data.split(",");
        ArrayList<TreeNode> queue = new ArrayList<>();
        TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
        queue.add(root);
        int index = 0;//index in queue
        boolean isLeftChild = true;
        for (int i = 1; i < vals.length; i++) {
            if (!vals[i].equals("#")) {
                TreeNode node = new TreeNode(Integer.parseInt(vals[i]));
                if (isLeftChild) {
                    queue.get(index).left = node;
                } else {
                    queue.get(index).right = node;
                }
                queue.add(node);
            }
            if (!isLeftChild) {
                index++;
            }
            isLeftChild = !isLeftChild;
        }
        return root;
    }

3. 二叉树的序列化

public String Serialize(TreeNode root) {
        if (root == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        ArrayList<TreeNode> queue = new ArrayList<>();
        queue.add(root);
        for (int i = 0; i < queue.size(); i++) {
            TreeNode node = queue.get(i);
            if (node == null)
                continue;
            queue.add(node.left);
            queue.add(node.right);
        }
        for (int i = 0; i < queue.size(); i++) {
            if (queue.get(i) == null)
                sb.append("#,");
            else
                sb.append("," + queue.get(i));
        }
        return sb.toString();
    }

4.找到节点的父节点的递归与非递归实现

由于此二叉树没有指向父亲的指针(三叉树有),所以需要从根结点root开始搜索current结点的父节点

public TreeNode getParentRecursively(TreeNode root, TreeNode node) {
        // 非递归实现查找某节点的父节点
        root = this.root;//从树的根结点开始找
        TreeNode temp;
        if (root == null) {
            return null;
        }
        if (node == root.left || node == root.right) {
            return root;
        }
        if ((temp = getParentRecursively(root.left, node)) != null) {
            return temp;
        }
        if ((temp = getParentRecursively(root.right, node)) != null) {
            return temp;
        }
        return null;
    }
public TreeNode getParentLooply(TreeNode node) {
        ArrayDeque<TreeNode> stack = new ArrayDeque<>();
        TreeNode currentRoot = this.root;
        stack.push(null);
        while (currentRoot != null) {
            if (node == currentRoot.left || node == currentRoot.right) {
                return currentRoot;
            }
            if (currentRoot.right != null) {
                stack.push(currentRoot.right);
            }
            if (currentRoot.left != null) {
                currentRoot = currentRoot.left;
            } else {
                currentRoot = stack.pop();
            }
        }
        return null;
    }

5.遍历二叉树的递归实现:

public void traversalRecursively(TreeNode root) {
        if (root != null) {
            //visit(root);this is preorder
            traversalRecursively(root.left);
//            visit(root);this is inorder
            traversalRecursively(root.right);
//            visit(root);this is postoder
        }
    }

6. 先序遍历的非递归实现

/*非递归的先序遍历
steps:
1:构建一个空栈,判断根不为空,并将根压入栈中
2如果栈不为空,从栈中取一个节点,访问它
3.并将其非空右孩子压栈,再将其非空左孩子压栈
4.重复2,3

public ArrayList<Integer> preOrder() {
        ArrayList<Integer> preOrder = new ArrayList<>();
        ArrayDeque<TreeNode> stack = new ArrayDeque<>();
        if (root == null)
            return preOrder;
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            preOrder.add(node.val);
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        return preOrder;
    }

7.中序遍历的非递归实现

steps:
1.遇到一个节点,将其压栈,并遍历其左子树。
2.遍历完左子树,从栈顶弹出一个结点并访问之。
3.按照其右链地址遍历该结点的右子树。

 public ArrayList<Integer> inOrder() {
        ArrayList<Integer> inorder=new ArrayList<>();
        ArrayDeque<TreeNode> stack=new ArrayDeque<>();
        if(root==null){
            return inorder;
        }
        TreeNode ptr=root;
        while(ptr!=null||!stack.isEmpty()){
            while(ptr!=null){
                stack.push(ptr);
                ptr=ptr.left;
            }
            ptr=stack.pop();
            inorder.add(ptr.val);
            ptr=ptr.right;
        }
        return inorder;
    }

8. 层次遍历二叉树,队列实现

public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
        // write your code here
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        ArrayDeque<TreeNode> queue = new ArrayDeque<>();
        if (root == null)
            return res;
        queue.offer(root);
        while (!queue.isEmpty()) {
            ArrayList<Integer> level = new ArrayList<>();
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                level.add(node.val);
                if (node.left != null)
                    queue.offer(node.left);
                if (node.right != null)
                    queue.offer(node.right);
            }
            res.add(level);
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值