树:用来模拟具有树状结构的数据集合。有节点组成。
特点:
- 每个节点子节点有限或无子节点
- 无父节点的节点成为根节点
- 每一个子节点只有一个父节点
- 树种左子节点<父节点<右子节点
- 树中没有环路
优点
- 树具有有序数组和链表的优点;
- 查询速度与有序数组相同(节点大小左小右大);增删与链表处理速度相同(节点存在前后指针)
定义树
import org.apache.log4j.Logger;
public class Tree
{
private static Logger logger = Logger.getLogger(Tree.class);
//根节点
private Node root = null;
//左节点
private Node left;
//右节点
private Node right;
//元素
private int data;
public Node getRoot() {
return root;
}
//添加元素
public void add(int data) {
Node node = new Node(data);
//如果根节点为空,自动设置为根节点
if(root==null) {
root = node;
}
//如果比根节点小,放入左子树
if(node.data<root.data) {
dealLeft(node);
}
//如果比根节点大,放入右子树
if(node.data>root.data) {
dealRight(node);
}
}
public void dealLeft(Node node) {
//若根节点左子树为空
if(root.left==null) {
root.left = node;
return;
}
//若左节点一直存在值,则循环合适的位置放入元素
Node leftNode = root;
while(leftNode!=null) {
//若元素比左子节点小,同时左子节点不存在子节点,则按顺序将左子节点做为父节点
if(node.data<leftNode.left.data&&leftNode.left.left==null) {
//将元素放入左子节点中
Node newNode = new Node(node.data);
leftNode.left.left = newNode;
//处理元素子节点
if(node.left!=null) {
dealLeft(node.left);
}
if(node.right!=null) {
dealLeft(node.right);
}
return;
}
if(node.data>leftNode.left.data) {
//若插入节点比左子树父节点大,则元素设置为左节点,处理原左子节点位置
Node oldLeftNode = leftNode.left;
leftNode.left = node;
dealLeft(oldLeftNode);
return;
}else if(node.data>leftNode.left.left.data&&leftNode.left.right==null){
//插入节点比左子树父节点小,但比左子节点大,同时右子节点为空
leftNode.left.right = node;
return;
}else if(node.data<leftNode.left.left.data&&leftNode.left.right==null) {
//插入节点比左子树父节点和左子节点小,同时右子节点空
leftNode.left.right = leftNode.left.left;
leftNode.left.left = node;
return;
}
leftNode = leftNode.left;
}
}
//右子树插入数据
public void dealRight(Node node) {
//若根节点右子树为空
if(root.right==null) {
root.right = node;
return ;
}
//循环右子树,找合适的位置插入
Node rightNode = root;
while(rightNode!=null) {
//若元素比右子节点小,同时右子节点不存在子节点,则按顺序将右子节点做为父节点
if(node.data<rightNode.right.data&&rightNode.right.left==null) {
//将元素放入左子节点中
Node newNode = new Node(node.data);
rightNode.right.left = newNode;
//处理元素子节点
if(node.left!=null) {
dealRight(node.left);
}
if(node.right!=null) {
dealRight(node.right);
}
return;
}
if(node.data>rightNode.right.data) {
//若插入节点比右子树父节点大,则元素设置为右节点,处理原左子节点位置
Node oldLeftNode = rightNode.right;
rightNode.right = node;
dealRight(oldLeftNode);
return;
}else if(node.data>rightNode.right.left.data&&rightNode.right.right==null){
//插入节点比左子树父节点小,但比左子节点大,同时右子节点为空
rightNode.right.right = node;
return;
}else if(node.data<rightNode.right.left.data&&rightNode.right.right==null) {
//插入节点比右子树父节点和右子节点小,同时右子节点空
rightNode.right.right = rightNode.right.left;
rightNode.right.left = node;
return;
}
rightNode = rightNode.right;
}
}
}
查询二叉树节点个数
public int NodeCount(int result,Node root) {
if(root==null) {
result = 0;
}else {
Node leftNode = root;
while(leftNode.left!=null) {
result++;
while(leftNode.left.right!=null) {
//若右子节点存在左子树,当成一颗新树循环左右子节点数
result = NodeCount(result,leftNode.left.right);
if(leftNode.left.right.left==null) {
break;
}
leftNode = leftNode.left.right.left;
}
leftNode = leftNode.left;
}
Node rightNode = root;
while(rightNode.right!=null) {
result++;
while(rightNode.right.left!=null) {
//若左子节点存在右子树,当成一颗新树循环左右子节点数
result = NodeCount(result,rightNode.right.left);
if(rightNode.right.left.left==null) {
break;
}
}
rightNode = rightNode.right;
}
result++;
}
return result;
}