一、首先要用到软件包 java.util中的接口 List<E>、接口 Queue<E>
import java.util.*;
以以下叉树为例:
/*
* 1
* / | \
* 3 2 4
* / | \ /|\ / | \
* 6 7 9 1 2 3 8
*
*
*
*/
二、设置一个类:class InThreadedBinaryTree
三、定义一个树的节点,为内部类。
三叉树的存储结构:private class Node
private class Node{
int item;
Node leftNode;
Node centerNode;
Node rightNode;
public Node(){
leftNode=null;
rightNode=null;
centerNode = null;
}
public Node(int item){
super();
this.item=item;
}
}
其中的item,后面在说。
四、设置以下参数:
private Node head;
public static final int FLAG=-1;//FLAG的目的是为了递归时判断有没有某一方向的子节点
FLAG的目的是为了递归时判断有没有某一方向的子节点。
五、设置头节点的三段方法:
public InThreadedBinaryTree(){
head=null;
}
public Node getHead() {
return head;
}
public void setHead(Node head) {
this.head = head;
}
注意:设置头节点(根节点),默认为空。
六、输入你要的数字为头:
public void initTBinaryTree(){
Scanner input=new Scanner(System.in);
int item;
System.out.print("Input the value of the root(-1 to exit):");
item=input.nextInt();
if(item!=FLAG)
{
head=new Node(item);
init(head);
}
}
七、递归创建:
private void init(Node head){
Scanner input=new Scanner(System.in);
int item;
//创建某结点的左子节点
System.out.print("Input the left child of the node("+
head.item+"):");
item=input.nextInt();
if(item!=FLAG)
{
head.leftNode=new Node(item);
init(head.leftNode);
}
//创建某结点的中子节点
System.out.print("Input the center child of the node("+
head.item+"):");
item=input.nextInt();
if(item!=FLAG)
{
head.centerNode=new Node(item);
init(head.centerNode);
}
//创建某结点右子节点
System.out.print("Input the right child of the node("+
head.item+")");
item=input.nextInt();
if(item!=FLAG)
{
head.rightNode=new Node(item);
init(head.rightNode);
}
}
注意:head.item是在initTBinaryTree中创建了Node的引用变量head并调用了item。
八、设置接口 List<E>、接口 Queue<E>
其中有以下几个类:
①、在接口 List<E>中,ArrayList<E>是List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素;add(E e)向列表的尾部添加指定的元素(可选操作)。
②、接口 Queue<E>中,ArrayDeque<>是Deque接口的大小可变数组的实现。数组双端队列没有容量限制;
从接口 java.util.Collection 继承的方法 |
add()将指定的元素插入此队列(如果立即可行且不会违反容量限制);
isEmpty()如果此 collection 即queue不包含元素,则返回 true。
size()返回此 collection 中的元素数。如果此 collection 包含的元素大于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE。返回:此 collection 中的元素数。
remove()从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
//队列方法
//创建整型双层整型队列
public List<List<Integer>> levelOrder(Node head) {
List<List<Integer>> list = new ArrayList<>();
if(head==null){
return null;
}
//建一个队列,用来遍历树
Queue<Node> queue = new ArrayDeque<>();
queue.add(head);
while (!queue.isEmpty()){
//集合用来保存每一层的结点
List<Integer> list1 = new ArrayList<>();
//可调整大小的数组的实现List接口。 每个ArrayList实例都有一个容量 。
//容量是用于存储列表中的元素的数组的大小。
//它总是至少与列表大小一样大。 当元素添加到ArrayList时,其容量会自动增长。
int size = queue.size();
for (int i = 0; i < size; i++) {
//出队
Node node = queue.remove();
//将结点值添加到集合
list1.add(node.item);
if(node.leftNode!=null){
queue.add(node.leftNode);
}
if(node.centerNode!=null){
queue.add(node.centerNode);
}
if(node.rightNode!=null){
queue.add(node.rightNode);
}
}
list.add(list1);
}
return list;
}
九、主方法中:
public class threeTree {
public static void main(String[] args) {
InThreadedBinaryTree tbTree=new InThreadedBinaryTree();
tbTree.initTBinaryTree();
System.out.println("层次遍历结果为: " + tbTree.levelOrder(tbTree.getHead()));
;
}
}
十、总代码:
import java.util.*;
/*
* 1
* / | \
* 3 2 4
* / | \ /|\ / | \
* 6 7 9 1 2 3 8
*
*
*
*/
//本次采用递归方法构建三叉树
public class threeTree {
public static void main(String[] args) {
InThreadedBinaryTree tbTree=new InThreadedBinaryTree();
tbTree.initTBinaryTree();
System.out.println("层次遍历结果为: " + tbTree.levelOrder(tbTree.getHead()));
;
}
}
class InThreadedBinaryTree{
// 定义一个树的节点
private class Node{
int item;
Node leftNode;
Node centerNode;
Node rightNode;
public Node(){
leftNode=null;
rightNode=null;
centerNode = null;
}
public Node(int item){
this.item=item;
}
}
private Node head;
public static final int FLAG=-1;//FLAG的目的是为了递归时判断有没有某一方向的子节点
//设置头节点(根节点),默认为空。
public InThreadedBinaryTree(){
head=null;
}
public Node getHead() {
return head;
}
public void setHead(Node head) {
this.head = head;
}
//输入你要的数字
public void initTBinaryTree(){
Scanner input=new Scanner(System.in);
int item;
System.out.print("Input the value of the root(-1 to exit):");
item=input.nextInt();
if(item!=FLAG)
{
head=new Node(item);
init(head);
}
}
//递归创建
private void init(Node head){
Scanner input=new Scanner(System.in);
int item;
//创建某结点的左子节点
System.out.print("Input the left child of the node("+
head.item+"):");//head.item是在initTBinaryTree中创建了Node的引用变量head并调用了item
item=input.nextInt();
if(item!=FLAG)
{
head.leftNode=new Node(item);
init(head.leftNode);
}
//创建某结点的中子节点
System.out.print("Input the center child of the node("+
head.item+"):");
item=input.nextInt();
if(item!=FLAG)
{
head.centerNode=new Node(item);
init(head.centerNode);
}
//创建某结点右子节点
System.out.print("Input the right child of the node("+
head.item+")");
item=input.nextInt();
if(item!=FLAG)
{
head.rightNode=new Node(item);
init(head.rightNode);
}
}
//队列方法
//创建整型双层整型队列
public List<List<Integer>> levelOrder(Node head) {
List<List<Integer>> list = new ArrayList<>();
if(head==null){
return null;
}
//建一个队列,用来遍历树
Queue<Node> queue = new ArrayDeque<>();
queue.add(head);
while (!queue.isEmpty()){
//集合用来保存每一层的结点
List<Integer> list1 = new ArrayList<>();
//可调整大小的数组的实现List接口。 每个ArrayList实例都有一个容量 。
//容量是用于存储列表中的元素的数组的大小。 它总是至少与列表大小一样大。 当元素添加到ArrayList时,其容量会自动增长。
int size = queue.size();
for (int i = 0; i < size; i++) {
//出队
Node node = queue.remove();
//将结点值添加到集合
list1.add(node.item);
if(node.leftNode!=null){
queue.add(node.leftNode);
}
if(node.centerNode!=null){
queue.add(node.centerNode);
}
if(node.rightNode!=null){
queue.add(node.rightNode);
}
}
list.add(list1);
}
return list;
}
}
结果运行:
感觉可以改进的地方:
1、可以加个确认是否有节点的判断,防止-1的过多输入。