树或者是一个空树,即不含有任何的结点(元素),或者是一个非空树,即至少含有一个结点。
构成一棵树,称为根结点的 子树。
得到一个森林;反之,加上一个结点作树根,森林就变为一棵树。
双亲在同一层的结点互为堂兄弟。树中结点的最大层数称为树的高度 (Height) 或深度 (Depth) 。很多
文献中将树根的层数定义为 0。
称根的 左子树 和 右子树 所组成的 非空树 ,左子树和右子树又同样都是一棵二叉树。 二叉树中,
每个结点的左子树的根结点被称为该结点的 左孩子 ( left child ) , 右子树的根结点被称为 右孩子
( left child )。
在最右边缺少连续若干个结点,则称此树为完全二叉树。
二叉树结点的定义:
二叉树存储结构结点定义
public interface Node {
//获取结点数据域
public Object getData();
//设置结点数据域
public void setData(Object obj);
}
public class BinTreeNode implements Node {
private Object data; //数据域
private BinTreeNode parent; //父结点
private BinTreeNode lChild; //左孩子
private BinTreeNode rChild; //右孩子
private int height; //以该结点为根的子树的高度
private int size; //该结点子孙数(包括结点本身)
public BinTreeNode() {
this(null);
}
public BinTreeNode(Object e) {
data = e;
parent = lChild = rChild = null;
height = 0;
size = 1;
}
public Object getData() {
return data;
}
public void setData(Object obj) {
data = obj;
}
//判断是否有父亲
public boolean hasParent() {
return parent != null;
}
//判断是否有左孩子
public boolean hasLChild() {
return lChild != null;
}
//判断是否有右孩子
public boolean hasRChild() {
return rChild != null;
}
//判断是否为叶子结点
public boolean isLeaf() {
return !hasLChild() && !hasRChild();
}
//判断是否为某结点的左孩子
public boolean isLChild() {
return (hasParent() && this == parent.lChild);
}
//判断是否为某结点的右孩子
public boolean isRChild() {
return (hasParent() && this == parent.rChild);
}
//取结点的高度,即以该结点为根的树的高度
public int getHeight() {
return height;
}
//更新当前结点及其祖先的高度
private void updateHeight() {
int newH = 0;//新高度初始化为0,高度等于左右子树高度加1中大的
if (hasLChild())
newH = Math.max(newH, 1 + getLChild().getHeight());
if (hasRChild())
newH = Math.max(newH, 1 + getRChild().getHeight());
if (newH == height)
return; //高度没有发生变化则直接返回
height = newH; //否则更新高度
if (hasParent())
getParent().updateHeight(); //递归更新祖先的高度
}
//取以该结点为根的树的结点数
public int getSize() {
return size;
}
//更新当前结点及其祖先的子孙数
private void updateSize() {
size = 1; //初始化为1,结点本身
if (hasLChild())
size += getLChild().getSize(); //加上左子树规模
if (hasRChild())
size += getRChild().getSize(); //加上右子树规模
if (hasParent())
getParent().updateSize(); //递归更新祖先的规模
}
//取父结点
public BinTreeNode getParent() {
return parent;
}
//断开与父亲的关系
private void sever() {
if (!hasParent())
return;
if (isLChild())
parent.lChild = null;
else
parent.rChild = null;
parent.updateHeight(); //更新父结点及其祖先高度
parent.updateSize(); //更新父结点及其祖先规模
parent = null;
}
//取左孩子
public BinTreeNode getLChild() {
return lChild;
}
//设置当前结点的左孩子,返回原左孩子
public BinTreeNode setLChild(BinTreeNode lc) {
BinTreeNode oldLC = this.lChild;
if (hasLChild()) {
lChild.sever();
} //断开当前左孩子与结点的关系
if (lc != null) {
lc.sever(); //断开lc与其父结点的关系
this.lChild = lc; //确定父子关系
lc.parent = this;
this.updateHeight(); //更新当前结点及其祖先高度
this.updateSize(); //更新当前结点及其祖先规模
}
return oldLC; //返回原左孩子
}
//取右孩子
public BinTreeNode getRChild() {
return rChild;
}
//设置当前结点的右孩子,返回原右孩子
public BinTreeNode setRChild(BinTreeNode rc) {
BinTreeNode oldRC = this.rChild;
if (hasRChild()) {
rChild.sever();
} //断开当前右孩子与结点的关系
if (rc != null) {
rc.sever(); //断开lc与其父结点的关系
this.rChild = rc; //确定父子关系
rc.parent = this;
this.updateHeight(); //更新当前结点及其祖先高度
this.updateSize(); //更新当前结点及其祖先规模
}
return oldRC; //返回原右孩子
}
}
三叉链表存储下的二叉树的实现:(三叉链表存储是指:二叉树的结点的存储单元包含4个域,1、数据域,2、左孩子域,3、父亲域,4、右孩子域。)
三叉链表存储下的二叉树的实现BinaryTreeLinked:
public interface BinTree {
//返回树的规模
public int getSize();
//判断树是否为空
public boolean isEmpty();
//返回根结点引用
public BinTreeNode getRoot();
//获取树的高度
public int getHeight();
//在树中查找元素e,返回其所在结点
public BinTreeNode find(Object e);
//先序遍历二叉树
public Iterator preOrder();
//中序遍历二叉树
public Iterator inOrder();
//后序遍历二叉树
public Iterator postOrder();
//按层遍历二叉树
public Iterator levelOrder();
}
三叉链表存储下的二叉树的实现BinaryTreeLinked
public interface BinTree {
// 返回树的规模
public int getSize();
// 判断树是否为空
public boolean isEmpty();
// 返回根结点引用
public BinTreeNode getRoot();
// 获取树的高度
public int getHeight();
// 在树中查找元素e,返回其所在结点
public BinTreeNode find(Object e);
// 先序遍历二叉树
public Iterator preOrder();
// 中序遍历二叉树
public Iterator inOrder();
// 后序遍历二叉树
public Iterator postOrder();
// 按层遍历二叉树
public Iterator levelOrder();
}
public class BinaryTreeLinked implements BinTree {
protected BinTreeNode root;
protected Strategy strategy;
public BinaryTreeLinked(){ this(null); }
public BinaryTreeLinked(BinTreeNode root) { this(root,new DefaultStrategy());}
public BinaryTreeLinked(BinTreeNode root, Strategy strategy){
this.root = root;
this.strategy = strategy;
}
// 返回树的规模
public int getSize() {
return root==null?0:root.getSize();
}
// 判断树是否为空
public boolean isEmpty() { return root==null;}
// 返回根结点引用
public BinTreeNode getRoot() { return root;}
// 获取树的高度
public int getHeight() { return isEmpty()?-1:root.getHeight();}
// 在树中查找元素e,返回其所在结点
public BinTreeNode find(Object e) {
return searchE(root,e);
}
// 递归查找元素e
private BinTreeNode searchE(BinTreeNode rt, Object e) {
if (rt==null) return null;
if (strategy.equal(rt.getData(),e)) return rt; // 如果是根结点,返回根
BinTreeNode v = searchE(rt.getLChild(),e); // 否则在左子树中找
if (v==null) v = searchE(rt.getRChild(),e); // 没找到,在右子树中找
return v;
}
// 先序遍历二叉树
public Iterator preOrder() {
LinkedList list = new LinkedListDLNode();
preOrderRecursion(this.root,list);
return list.elements();
}
// 先序遍历的递归算法
private void preOrderRecursion(BinTreeNode rt, LinkedList list){
if (rt==null) return; // 递归基,空树直接返回
list.insertLast(rt); // 访问根结点
preOrderRecursion(rt.getLChild(),list); // 遍历左子树
preOrderRecursion(rt.getRChild(),list); // 遍历右子树
}
// 先序遍历的非递归算法
private void preOrderTraverse(BinTreeNode rt, LinkedList list){
if (rt==null) return;
BinTreeNode p = rt;
Stack s = new StackSLinked();
while (p!=null){
while (p!=null){ // 向左走到尽头
list.insertLast(p); // 访问根
if (p.hasRChild()) s.push(p.getRChild()); // 右子树根结点入栈
p = p.getLChild();
}
if (!s.isEmpty()) p = (BinTreeNode)s.pop(); // 右子树根退栈遍历右子树
}
}
// 中序遍历二叉树
public Iterator inOrder(){
LinkedList list = new LinkedListDLNode();
inOrderRecursion(this.root,list);
return list.elements();
}
// 中序遍历的递归算法
private void inOrderRecursion(BinTreeNode rt, LinkedList list){
if (rt==null) return; // 递归基,空树直接返回
inOrderRecursion(rt.getLChild(),list); // 遍历左子树
list.insertLast(rt); // 访问根结点
inOrderRecursion(rt.getRChild(),list); // 遍历右子树
}
// 中序遍历的非递归算法
private void inOrderTraverse(BinTreeNode rt, LinkedList list){
if (rt==null) return;
BinTreeNode p = rt;
Stack s = new StackSLinked();
while (p!=null||!s.isEmpty()){
while (p!=null){ // 一直向左走
s.push(p); // 将根结点入栈
p = p.getLChild();
}
if (!s.isEmpty()){
p = (BinTreeNode)s.pop();// 取出栈顶根结点访问之
list.insertLast(p);
p = p.getRChild(); // 转向根的右子树进行遍历
}// if
}// out while
}
// 后序遍历二叉树
public Iterator postOrder(){
LinkedList list = new LinkedListDLNode();
postOrderRecursion(this.root,list);
return list.elements();
}
// 后序遍历的递归算法
private void postOrderRecursion(BinTreeNode rt, LinkedList list){
if (rt==null) return; // 递归基,空树直接返回
postOrderRecursion(rt.getLChild(),list);// 遍历左子树
postOrderRecursion(rt.getRChild(),list);// 遍历右子树
list.insertLast(rt); // 访问根结点
}
// 后序遍历的非递归算法
private void postOrderTraverse(BinTreeNode rt, LinkedList list){
if (rt==null) return;
BinTreeNode p = rt;
Stack s = new StackSLinked();
while(p!=null||!s.isEmpty()){
while (p!=null){ // 先左后右不断深入
s.push(p); // 将根节点入栈
if (p.hasLChild()) p = p.getLChild();
else p = p.getRChild();
}
if (!s.isEmpty()){
p = (BinTreeNode)s.pop(); // 取出栈顶根结点访问之
list.insertLast(p);
}
// 满足条件时,说明栈顶根节点右子树已访问,应出栈访问之
while (!s.isEmpty()&&((BinTreeNode)s.peek()).getRChild()==p){
p = (BinTreeNode)s.pop();
list.insertLast(p);
}
// 转向栈顶根结点的右子树继续后序遍历
if (!s.isEmpty()) p = ((BinTreeNode)s.peek()).getRChild();
else p = null;
}
}
// 按层遍历二叉树
public Iterator levelOrder(){
LinkedList list = new LinkedListDLNode();
levelOrderTraverse(this.root,list);
return list.elements();
}
// 使用对列完成二叉树的按层遍历
private void levelOrderTraverse(BinTreeNode rt, LinkedList list){
if (rt==null) return;
Queue q = new QueueArray();
q.enqueue(rt); // 根结点入队
while (!q.isEmpty()){
BinTreeNode p = (BinTreeNode)q.dequeue(); // 取出队首结点p并访问
list.insertLast(p);
if (p.hasLChild()) q.enqueue(p.getLChild());// 将p的非空左右孩子依次入队
if (p.hasRChild()) q.enqueue(p.getRChild());
}
}
}