标题:Java实现通过中序,后序遍历得到二叉树
感觉做完这个后,可以看一看Java实现通过前序,中序遍历得到二叉树
一、题解
方法一:使用递归,很容易想到
/**
*中后
*执行用时:4 ms, 在所有 Java 提交中击败了45.70% 的用户
内存消耗:38.2 MB, 在所有 Java 提交中击败了99.17% 的用户
* @return
*/
public TreeNode inPostOrder(Integer[] a, Integer[] b, int as, int ae, int bs, int be) {
if(as > ae || bs > be) {
return null;
}else {
TreeNode node = new TreeNode(b[be]);
int i = 0;
for(;i <= ae; i++) {
if(a[i] == b[be]) {
break;
}
}
node.left = this.inPostOrder(a, b, as, i - 1, bs, bs + (i - 1) - as);
node.right = this.inPostOrder(a, b, i + 1, ae, bs + (i - 1) - as + 1, be - 1);
return node;
}
}
方法二:使用迭代,感觉这个是递归的迭代版,我是先写的递归版本的
/**
* 迭代
* 执行用时:12 ms, 在所有 Java 提交中击败了12.45% 的用户
内存消耗:38.1 MB, 在所有 Java 提交中击败了99.39% 的用户
* @param a
* @param b
* @return
*/
public TreeNode inPostOrder02(Integer[] a, Integer[] b) {
if(a == null || b == null || a.length == 0 || b.length == 0) {
return null;
}
//创建一个内部类 为了保存状态 【保存现场 哈哈哈哈】
class MyNt{
int as;
int ae;
int bs;
int be;
TreeNode node;
public MyNt(int as, int ae, int bs, int be, TreeNode node) {
super();
this.as = as;
this.ae = ae;
this.bs = bs;
this.be = be;
this.node = node;
}
}
int as = 0;
int ae = a.length - 1;
int bs = 0;
int be = b.length - 1;
TreeNode head = new TreeNode(b[be]);
MyNt nt = new MyNt(as, ae, bs, be, head);
Deque<MyNt> s = new LinkedList<>();
s.push(nt);
while(!s.isEmpty()) {
nt = s.pop();
TreeNode node = nt.node;
as = nt.as;
ae = nt.ae;
bs = nt.bs;
be = nt.be;
//找到i后,将原来的数组分割
int i = as;
for(;i <= ae; i++) {
if(a[i] == b[be]) {
break;
}
}
//先放右边,再放左边
if(i + 1 <= ae) {
node.right = new TreeNode(b[be - 1]);
s.push(new MyNt(i + 1, ae, bs + (i - 1) - as + 1, be - 1, node.right)); //细心,be
}
if(as <= i - 1) {
node.left = new TreeNode(b[bs + (i - 1) - as]);
s.push(new MyNt(as, i - 1, bs, bs + (i - 1) - as, node.left));
}
}
return head;
}
完整示例代码如下:
/**
* 测试中后
* @author dell
*
*/
public class TestInPostOrder {
/**
*中后
*执行用时:4 ms, 在所有 Java 提交中击败了45.70% 的用户
内存消耗:38.2 MB, 在所有 Java 提交中击败了99.17% 的用户
* @return
*/
public TreeNode inPostOrder(Integer[] a, Integer[] b, int as, int ae, int bs, int be) {
if(as > ae || bs > be) {
return null;
}else {
TreeNode node = new TreeNode(b[be]);
int i = 0;
for(;i <= ae; i++) {
if(a[i] == b[be]) {
break;
}
}
node.left = this.inPostOrder(a, b, as, i - 1, bs, bs + (i - 1) - as);
node.right = this.inPostOrder(a, b, i + 1, ae, bs + (i - 1) - as + 1, be - 1);
return node;
}
}
/**
* 迭代
* 执行用时:12 ms, 在所有 Java 提交中击败了12.45% 的用户
内存消耗:38.1 MB, 在所有 Java 提交中击败了99.39% 的用户
* @param a
* @param b
* @return
*/
public TreeNode inPostOrder02(Integer[] a, Integer[] b) {
if(a == null || b == null || a.length == 0 || b.length == 0) {
return null;
}
//创建一个内部类 为了保存状态 【保存现场 哈哈哈哈】
class MyNt{
int as;
int ae;
int bs;
int be;
TreeNode node;
public MyNt(int as, int ae, int bs, int be, TreeNode node) {
super();
this.as = as;
this.ae = ae;
this.bs = bs;
this.be = be;
this.node = node;
}
}
int as = 0;
int ae = a.length - 1;
int bs = 0;
int be = b.length - 1;
TreeNode head = new TreeNode(b[be]);
MyNt nt = new MyNt(as, ae, bs, be, head);
Deque<MyNt> s = new LinkedList<>();
s.push(nt);
while(!s.isEmpty()) {
nt = s.pop();
TreeNode node = nt.node;
as = nt.as;
ae = nt.ae;
bs = nt.bs;
be = nt.be;
//找到i后,将原来的数组分割
int i = as;
for(;i <= ae; i++) {
if(a[i] == b[be]) {
break;
}
}
//先放右边,再放左边
if(i + 1 <= ae) {
node.right = new TreeNode(b[be - 1]);
s.push(new MyNt(i + 1, ae, bs + (i - 1) - as + 1, be - 1, node.right)); //细心,be
}
if(as <= i - 1) {
node.left = new TreeNode(b[bs + (i - 1) - as]);
s.push(new MyNt(as, i - 1, bs, bs + (i - 1) - as, node.left));
}
}
return head;
}
/**
* 初始化一个tree
* 类广度遍历
* @param a
* @return
*/
public TreeNode initTree(Integer[] a) {
if(a == null || a.length == 0) {
return null;
}
int t = 0;
TreeNode p = new TreeNode(a[t]); //至少有一个元素
Queue<TreeNode> q = new LinkedList<>();
q.offer(p);
while(!q.isEmpty()) {
TreeNode node = q.poll();
if(t + 1 == a.length) { //先判断数组中是否还有下一个元素
return p;
}else {
t++;
if(a[t] == null) { //若下一个元素为null,则不需要创建新的节点
node.left = null;
}else {
node.left = new TreeNode(a[t]);
q.offer(node.left);
}
}
if(t + 1 == a.length) {
return p;
}else {
t++;
if(a[t] != null){ //上面的简写,a[t] == null,不需要再赋值
node.right = new TreeNode(a[t]);
q.offer(node.right);
}
}
}
return p;
}
@Test
public void test() {
Integer[] arr = new Integer[] {1, 2, 3, 4, 5, 9, 10, null, 6, 7, 8, null, null, null, 11};
TreeNode head = this.initTree(arr);
List<Integer> lista = new ArrayList<>();
List<Integer> listb = new ArrayList<>();
System.out.println("\n输出中序遍历:");
this.inOrder(head, lista);
System.out.println("\n输出后序遍历:");
this.postOrder(head, listb);
Integer[] a = new Integer[lista.size()];
Integer[] b = new Integer[listb.size()];
lista.toArray(a);
listb.toArray(b);
System.out.println("\n输出中序遍历");
head = this.inPostOrder(a, b, 0, a.length - 1, 0, b.length - 1);
this.inOrder(head, lista);
System.out.println("\n输出中序遍历");
head = this.inPostOrder02(a, b);
this.inOrder(head, lista);
}
/**
* 中序遍历
* @param head
* @param list
*/
public void inOrder(TreeNode head, List<Integer> list) {
if(head == null) {
return ;
}else {
this.inOrder(head.left, list);
list.add(head.val);
System.out.print(head.val + " ");
this.inOrder(head.right, list);
}
}
/**
* 后序遍历
* @param head
* @param list
*/
public void postOrder(TreeNode head, List<Integer> list) {
if(head == null) {
return ;
}else {
this.postOrder(head.left, list);
this.postOrder(head.right, list);
list.add(head.val);
System.out.print(head.val + " ");
}
}
}