一、前言:
这是怀化学院的:Java数据结构中的一道难度偏难(偏难理解)的一道编程题(此方法为博主自己研究,问题基本解决,若有bug欢迎下方评论提出意见,我会第一时间改进代码,谢谢!) 后面其他编程题只要我写完,并成功实现,会陆续更新,记得三连哈哈! 所有答案供参考,不是标准答案,是博主自己研究的写法。(这一个题书上也有现成类似的代码,重要的是理解它的算法原理!)
二、题目要求如下:
(第 12 题) 链式二叉树的创建及遍历(难度系数100)
链式二叉树的创建及遍历
描述:
树的遍历有先序遍历、中序遍历和后序遍历。先序遍历的操作定义是先访问根结点,然后访问左子树,最后访问右子树。中序遍历的操作定义是先访问左子树,然后访问根,最后访问右子树。后序遍历的操作定义是先访问左子树,然后访问右子树,最后访问根。对于采用链式存储结构的二叉树操作中,创建二叉树通常采用先序次序方式输入二叉树中的结点的值,空格表示空树。对于如下的二叉树,我们可以通过如下输入“AE-F--H--”得到( ‘-’表示空子树)。试根据输入创建对应的链式二叉树,并输入其先序、中序和后序遍历结果。
输入:
输入第一行为一个自然数n,表示用例个数
接下来为n行字符串,每行用先序方式输入的要求创建的二叉树结点,’-’表示前一结点的子树为空子树。
输出:
对每个测试用例,分别用三行依次输出其先序、中序和后序遍历结果。
样例输入:
1
abdh---e-i--cf-j--gk---
样例输出:
abdheicfjgk
hdbeiafjckg
hdiebjfkgca
三、代码实现: (代码的做题原理全部在代码注释中,若还有疑问也可以翻书关于二叉树的链式存储结构以及二叉树的遍历以及递归实现的内容)
<1>因为学校的提交测试的网站:不能有自己创建的包的声明,不能有代码注释以及要把所有的操作放在同一个类中等等......,所以我首先放一个干净的代码实现:(此题提交成功!)
import java.util.Scanner;
public class Main {
private static class Node{
char data;
Node lChild;
Node rChild;
public Node(char data){
this.data=data;
}
}
private static int num=0;
public static Node setNode(Node node,String point){
if(num<point.length()){
char c =point.charAt(num++);
if (c != '-') {
node= new Node(c);
node.lChild= setNode(node.lChild,point);
node.rChild= setNode(node.rChild,point);
}else {
node=null;
}
}
return node;
}
private static Node root=null;
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int n = sc.nextInt();
while (n>0){
String point=sc.next();
root = setNode(root,point);
preOrder();
inOrder();
postOrder();
num=0;
n--;
}
}
public static void preOrder(){
preOrder(root);
System.out.println();
}
public static void preOrder(Node node){
if(node!=null){
System.out.print(node.data);
preOrder(node.lChild);
preOrder(node.rChild);
}
}
public static void inOrder(){
inOrder(root);
System.out.println();
}
public static void inOrder(Node node){
if(node!=null){
inOrder(node.lChild);
System.out.print(node.data);
inOrder(node.rChild);
}
}
public static void postOrder(){
postOrder(root);
System.out.println();
}
public static void postOrder(Node node){
if(node!=null){
postOrder(node.lChild);
postOrder(node.rChild);
System.out.print(node.data);
}
}
}
(1)全部放在一个类中去实现题目的所有要求。(其中注意创建了一个结点内部类)
import java.util.Scanner;
public class Main04 {
//静态结点内部类(不这样的话主方法里用不了)
private static class Node{
char data; //当前结点的存放的数据
Node lChild; //左孩子结点
Node rChild; //右孩子结点
public Node(char data){
this.data=data;
}
}
private static int num=0;
//要设为静态方法,不然主方法无法用
//此方法是按照先序次序方式创建二叉树
public static Node setNode(Node node,String point){
//从下标0开始依次添加结点
if(num<point.length()){
char c =point.charAt(num++); //注意这里每赋值完一个会往后移
if (c != '-') {
node= new Node(c); //这里给每个创建的新结点只要不是空结点就赋值
//先左结点,再创建右结点
node.lChild= setNode(node.lChild,point);
node.rChild= setNode(node.rChild,point);
}else {
node=null;
}
}
return node;
}
//创建应该初始的空根结点,也是要静态的变量才行
private static Node root=null;
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int n = sc.nextInt();
while (n>0){
String point=sc.next();
root = setNode(root,point);
preOrder();
inOrder();
postOrder();
num=0; //每次记得重置一下,因为这个我测试了好久才发现这个小错误
n--;
}
}
//实现先序遍历("根"结点 -> 左孩子 -> 右孩子)
public static void preOrder(){
preOrder(root);
System.out.println(); //遍历完记得换行
}
public static void preOrder(Node node){
//首先判断传进来的"根结点"是否为空
if(node!=null){
//只要不为空就先输出当前"根结点"并继续遍历其左孩子,直到左孩子无左右孩子,再输出当前"根结点",再往前递归
System.out.print(node.data);
preOrder(node.lChild);
preOrder(node.rChild);
}
}
//实现中序遍历(左孩子 -> "根"结点 ->右孩子)
public static void inOrder(){
inOrder(root);
System.out.println(); //遍历完记得换行
}
public static void inOrder(Node node){
//首先判断传进来的"根结点"是否为空,然后先遍历左孩子,直到左孩子的左孩子为空,那就输出当前的"根结点",再遍历右孩子,再往前递归
if(node!=null){
inOrder(node.lChild);
System.out.print(node.data);
inOrder(node.rChild);
}
}
//实现后序遍历(左孩子 -> 右孩子 ->"根"结点 )
public static void postOrder(){
postOrder(root);
System.out.println(); //遍历完记得换行
}
public static void postOrder(Node node){
//首先判断传进来的"根结点"是否为空,然后先遍历左孩子,直到左孩子的左右孩子为空,那就输出当前的"根结点",再往前递归
if(node!=null){
postOrder(node.lChild);
postOrder(node.rChild);
System.out.print(node.data);
}
}
}
四、不同情况的代码测试运行结果:
<1>首先是题目中的测试输入样例:(最好手打输入测试,直接复制可能格式问题导致报错!)
<2>其他: