面试题8:二叉树的下一个结点

题目:

给定一棵二叉树和其中的一个结点,如果找出中序遍历序列的下一个结点?树中的结点除了两个分别指向左、右子结点的指针,还有一个指向父结点的指针。

分析:

以这棵树为例,它的中序遍历序列是{d,b,h,e,i,a,f,c,g}。树中从父结点到子结点的指针用实线表示,从子结点到父结点的指针用虚线表示。下面观察a,f,i这三个结点,它们分别对应3种不同的情况。

a结点:它的下一个结点是f。a结点有右孩子,那么a结点的下一个结点就是从右孩子出发一直沿着左孩子方向找到的最后一个结点。

f结点:它的下一个结点是c。f结点没有右孩子,并且当前结点是父结点的左孩子,那么它的下一个结点是它的父结点。

i结点:它的下一个结点是a。i结点没有右孩子,并且当前结点是父结点的右孩子,那么沿着父结点向上找,直到找到这种情况:某个结点是当前结点父结点的左孩子。如果能找到这样的结点,那么这个结点的父结点就是要查找的下一个结点。如果找不到这样的结点,那么就没有下一个结点。

解法:

package com.wsy;

class Tree {
    private char value;
    private Tree left;
    private Tree right;
    private Tree parent;

    public Tree() {
    }

    public Tree(char value) {
        this.value = value;
        this.left = this.right = this.parent = null;
    }

    public Tree(char value, Tree left, Tree right, Tree parent) {
        this.value = value;
        this.left = left;
        this.right = right;
        this.parent = parent;
    }

    public char getValue() {
        return value;
    }

    public void setValue(char value) {
        this.value = value;
    }

    public Tree getLeft() {
        return left;
    }

    public void setLeft(Tree left) {
        this.left = left;
    }

    public Tree getRight() {
        return right;
    }

    public void setRight(Tree right) {
        this.right = right;
    }

    public Tree getParent() {
        return parent;
    }

    public void setParent(Tree parent) {
        this.parent = parent;
    }
}

public class Main {
    public static void main(String[] args) {
        Tree a = new Tree('a');
        Tree b = new Tree('b');
        Tree c = new Tree('c');
        Tree d = new Tree('d');
        Tree e = new Tree('e');
        Tree f = new Tree('f');
        Tree g = new Tree('g');
        Tree h = new Tree('h');
        Tree i = new Tree('i');
        a.setLeft(b);
        a.setRight(c);
        a.setParent(null);
        b.setLeft(d);
        b.setRight(e);
        b.setParent(a);
        c.setLeft(f);
        c.setRight(g);
        c.setParent(a);
        d.setLeft(null);
        d.setRight(null);
        d.setParent(b);
        e.setLeft(h);
        e.setRight(i);
        e.setParent(b);
        f.setLeft(null);
        f.setRight(null);
        f.setParent(c);
        g.setLeft(null);
        g.setRight(null);
        g.setParent(c);
        h.setLeft(null);
        h.setRight(null);
        h.setParent(e);
        i.setLeft(null);
        i.setRight(null);
        i.setParent(e);
        getNext(a);
        getNext(b);
        getNext(c);
        getNext(d);
        getNext(e);
        getNext(f);
        getNext(g);
        getNext(h);
        getNext(i);
    }

    public static void getNext(Tree tree) {
        if (tree == null) {
            System.out.println("It has not next element.");
            return;
        }
        System.out.print(tree.getValue() + ":");
        if (tree.getRight() != null) {
            tree = tree.getRight();
            while (tree.getLeft() != null) {
                tree = tree.getLeft();
            }
            System.out.println("It has next element:" + tree.getValue());
        } else {
            Tree parent = tree.getParent();
            if (parent == null) {
                System.out.println("It has not next element.");
            } else {
                while (parent != null && parent.getRight() == tree) {
                    tree = parent;
                    parent = parent.getParent();
                }
                if (parent == null) {
                    System.out.println("It has not next element.");
                } else {
                    System.out.println("It has next element:" + parent.getValue());
                }
            }
        }
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值