1.问题概述
2.问题分析:
3.解题思路:
4.代码实现:
package Tree;
import Queue.Queue;
public class pageFoldingTest {
public static void main(String[] args) {
//折纸问题
//1.模拟折纸过程,产生树
Node<String> tree=createTree(3);
//2.遍历树,打印每个节点
printTree(tree);
}
//通过模拟对折N次纸产生树
public static Node<String> createTree(int N){
//定义根节点
Node<String> root=null;
//模拟对折过程
for(int i=0;i<N;i++){
//当前是第一次对折
if(i==0){
root=new Node("down",null,null);
continue;
}
//当前不是第一次对折
//1.定义一个辅助队列,通过层次遍历的思想,找到叶子节点,给叶子节点添加子节点
Queue<Node> nodes =new Queue();
nodes.InQueue(root);
//循环遍历队列
while(!nodes.isEmpty()){
//从队列中弹出一个节点
Node<String> curr=nodes.OutQueue();
//如果有左子节点,则把左子节点放到队列中
if(curr.left!=null){
nodes.InQueue(curr.left);
}
//如果有右子节点,则把右子节点放入到队列中
if(curr.right!=null){
nodes.InQueue(curr.right);
}
//如果同时没有左子节点和右子节点那么证明该节点是叶子节点,只需要给该节点添加左子节点和右子节点即可
if(curr.left==null && curr.right==null){
curr.left=new Node<String>("down",null,null);
curr.right=new Node<String>("up",null,null);
}
}
}
return root;
}
//打印树中的每个节点
public static void printTree(Node<String> root){
//需要使用中序遍历完成
//安全性校验
if(root==null){
return;
}
//打印左子树
if(root.left!=null){
printTree(root.left);
}
//打印当前节点
System.out.print(root.item+" ");
//打印右子树
if(root.right!=null){
printTree(root.right);
}
}
//提供一个产生节点的内部类
public static class Node<T>{
//存储数据
T item;
//指向左子树
Node left;
//指向右子树
Node right;
//构造方法
public Node(T item, Node left, Node right) {
super();
this.item = item;
this.left = left;
this.right = right;
}
}
}
5.运行结果:
6.总结:
核心思想:
1.把折纸问题转换成树的模型
2.定义两个方法,分别模拟折纸(生成树),和打印树(中序遍历)
3.生成树的主要思想是,把每一次对折看成是多添加一层满二叉树,即2的n-1次方为每层的节点数;由此可以转换成层次模型,
4.再层次模型中利用一个辅助队列来存储该树的节点,(每一次循环都刷新队列元素(即每一次循环都从根节点如队列开始,然后弹出根节点判断有没有左子节点和右子节点,如果有则入队列,如果同时没有左右子节点那就是叶子节点,那么就为改节点创建左右子节点,再下一次循环的刷新队列中重新入队列即可,然后循环上面步骤,直至到第N次为止,直到最后一次循环队列中的元素都出队列了就代表树生成了。
5.采用中序遍历的方式将树打印出来即可。