输入一个整数n(n <= 100000),表示二叉树中结点个数,编号为1~n。约定1号结点为二叉树的根节点。然后输入n行,每行包括两个整数,第i行表示编号为i的结点的左子节点和右子节点的编号。如果某个结点没有左子节点,那么对应输行的第一个整数为0;如果某个结点没有右子节点,那么对应行的第二个整数为0。
先序遍历输出此二叉树每个结点的编号,每行输出一个编号。先序遍历(DLR),是二叉树遍历的一种,也叫做先根遍历、前序遍历、前序周游,可记做根左右。前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。
输入第一行:一个整数n
接下来n行,每行有两个整数输出输出n行,每行一个整数,表示节点编号。输入样例
5
2 5
3 4
0 0
0 0
0 0
输出样例
1
2
3
4
5
看到这题的第一想法是使用数组模拟二叉树,使用2n+1,2n+2公式遍历
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] l = new int[3*n+1];
l[0]=1;
for (int i = 0; i < n; i++) {
l[2*i+1]=sc.nextInt();
l[2*i+2]=sc.nextInt();
}
f(l,0);
}
private static void f(int[] l,int i) {
System.out.println(l[i]);
if (l[2*i+1]!=0) f(l,2*i+1);
if (l[2*i+2]!=0) f(l,2*i+2);
}
结果出现了数组超限的问题,但是如果改大的话根据2n+1公式依次计算将会是很大的数组,这个方法显然行不通,只能建立二叉树
import java.util.Scanner;
public class c {
public static class heronode{
private int no;
private heronode left;
private heronode right;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
heronode h = new heronode();
h.no=1;
for (int i = 1; i <= n; i++) {
heronode l = new heronode();
heronode r = new heronode();
l.no=sc.nextInt();
r.no=sc.nextInt();
d(h,l,r,i);
}
f(h);
}
private static void d(heronode h, heronode l, heronode r, int i) {
if (h.no==i) {
if(l.no!=0) h.left=l;
if(r.no!=0) h.right=r;
}
if (h.left!=null) d(h.left,l,r,i);
if (h.right!=null) d(h.right,l,r,i);
}
private static void f(heronode l) {
System.out.println(l.no);
if (l.left!=null) f(l.left);
if (l.right!=null) f(l.right);
}
}
但是发现代码开始超时,测试给出的数据量很大,这样会存在两层查找,所以只能再次改变方法,使用数组加二叉树
heronode[] hero = new heronode[1000010];
for (int i = 0; i <= n; i++) {
hero[i]=new heronode();
hero[i].no=i;
}
for (int i = 1; i <= n; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
hero[i].left=hero[a];
hero[i].right=hero[b];
}
f(hero[1]);
此时只要遍历二叉树就行了,省去一层查找
private static void f(heronode h) {
if (h.no!=0) {
System.out.println(h.no);
f(h.left);
f(h.right);
}
}