数据结构--树

树:用来模拟具有树状结构的数据集合。有节点组成。

特点:

  • 每个节点子节点有限或无子节点
  • 无父节点的节点成为根节点
  • 每一个子节点只有一个父节点
  • 树种左子节点<父节点<右子节点
  • 树中没有环路

优点

  • 树具有有序数组和链表的优点;
  • 查询速度与有序数组相同(节点大小左小右大);增删与链表处理速度相同(节点存在前后指针)

定义树

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;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值