package com.supermars.practice;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Vector;
public class 无根树转有根树 {
static Scanner cin = new Scanner(System.in);
static Vector<Integer> G[] = new Vector[1 << 7];
static int p[];;
public static void main(String[] args) {
while (cin.hasNext()) {
int n = cin.nextInt();
p = new int[n];
for (int i = 0; i < n - 1; i++) { // n-1条边
int u = cin.nextInt();
int v = cin.nextInt();
if (G[u] == null)
G[u] = new Vector<Integer>();
G[u].add(v);
if (G[v] == null)
G[v] = new Vector<Integer>();
G[v].add(u);
}
Arrays.fill(p, -1);
dfs(1, -1);// 节点1开始为跟,-1表示无父节点
// System.out.println(Arrays.toString(p));
}
}
private static void dfs(int u, int fa) {
int d = G[u].size();// 多少个u节点的相邻节点
for (int i = 0; i < d; i++) {
int v = G[u].get(i); // u的相邻节点i
if (v != fa) {
dfs(v, p[v] = u); // 保存v节点的父亲u
System.out.println(v + "的父节点" + p[v]);
}
}
}
}
package com.supermars.practice;
import java.util.Scanner;
public class 表达式树 {
static Scanner cin = new Scanner(System.in);
static final int MAXN = 1 << 7;
static char input[]; // 2+3*(4-1)-5/1 表达式字符串
static char op[] = new char[MAXN]; // 节点中的操作符
static int lch[] = new int[MAXN]; // 每个节点的左右儿子
static int rch[] = new int[MAXN];
static int nc = 0;// 节点个数
public static void main(String[] args) {
while (cin.hasNext()) {
input = cin.nextLine().toCharArray();
bulidTree(input, 0, input.length);
System.out.println(transTree(0));
}
}
private static int bulidTree(char[] s, int x, int y) {
int c1 = -1, c2 = -1, p = 0;
int u;
if (y - x == 1) { // 只剩余一个操作字符节点
u = nc++;
lch[u] = rch[u] = 0; // 操作字符无左右子树
op[u] = s[x]; // 保存操作字符
return u;
}
// c1 最后+- c2最后*/的位置
for (int i = x; i < y; i++) {
switch (s[i]) {
case '(':
p++;
break;
case ')':
p--;
break;
case '+':
case '-':
if (p == 0) // 在括号外
c1 = i; // 最后+-的位置
break;
case '*':
case '/':
if (p == 0) // 最后*/的位置
c2 = i;
break;
}
}
if (c1 < 0)
c1 = c2; // 括号外没有加减
if (c1 < 0)
return bulidTree(s, x + 1, y - 1);// 求解[x+1,y-1]构造表达式
u = nc++; // c1划分左右子树,
lch[u] = bulidTree(s, x, c1); // 构造左子树
rch[u] = bulidTree(s, c1 + 1, y);
op[u] = s[c1]; // 存节点操作字符
return u;
}
private static int transTree(int cur) {
if (lch[cur] == 0 || rch[cur] == 0) { // 叶子节点返回值
return op[cur] - '0';
} else {
int retl = transTree(lch[cur]); // 计算左子树的值
int retr = transTree(rch[cur]);
int ret = 0;
switch (op[cur]) { // 根据当前节点分别计算左右子树+-*/的结果
case '+':
ret = (retl + retr);
break;
case '-':
ret = (retl - retr);
break;
case '*':
ret = (retl * retr);
break;
case '/':
ret = (retl / retr);
break;
}
// System.out.println(ret);
return ret;
}
}
}