packagecom.clarck.datastructure.binarytree;importcom.clarck.datastructure.queue.LinkedQueue;importcom.clarck.datastructure.queue.SeqQueue;importcom.clarck.datastructure.stack.LinkedStack;/*** 二叉树类,实现BinaryTTree接口,泛型T指定结点的元素类型
*
*@authorclarck
*
*@param*/
public class BinaryTree implements BinaryTTree{//根结点,结点结构为二叉链表
public BinaryNoderoot;/*** 构造空二叉树*/
publicBinaryTree() {this.root = null;
}/*** 判断二叉树是否为空*/@Overridepublic booleanisEmpty() {return this.root == null;
}/*** 二叉树的先根、中根和后根次序遍历算法
*
* 先根次序遍历二叉树*/@Overridepublic voidpreOrder() {
System.out.print("先根次序遍历二叉树:");//调用先根次序遍历二叉树的递归方法
preOrder(root);
System.out.println();
}/*** 先根次序遍历以p结点为根的子二叉树,递归方法
*
*@paramp*/
private void preOrder(BinaryNodep) {if (p != null) {//访问当前结点
System.out.print(p.data.toString() + " ");//按先根次序遍历当前结点的左子树,递归调用
preOrder(p.left);//按先根次序遍历当前结点的右子树,递归调用
preOrder(p.right);
}
}/*** 中根次序遍历二叉树*/@Overridepublic voidinOrder() {
System.out.print("中根次序遍历二叉树: ");
inOrder(root);
System.out.println();
}/*** 中根次序遍历以p结点为根的子二叉树,递归方法
*
*@paramp*/
private void inOrder(BinaryNodep) {if (p != null) {//中根次序遍历左子树
inOrder(p.left);
System.out.print(p.data.toString()+ " ");//中根次序遍历右子树
inOrder(p.right);
}
}/*** 后根次序遍历二叉树*/@Overridepublic voidpostOrder() {
System.out.print("后根次序遍历二叉树: ");
postOrder(root);
System.out.println();
}/*** 后根次序遍历以p结点为根的子二叉树,递归方法
*
*@paramp*/
private void postOrder(BinaryNodep) {if (p != null) {
postOrder(p.left);
postOrder(p.right);
System.out.print(p.data.toString()+ " ");
}
}/*** 二叉树的层次遍历
*
* 按层次遍历二叉树*/@Overridepublic voidlevelOrder() {
System.out.print("层次遍历二叉树: ");//创建一个空队列
SeqQueue> que = new SeqQueue>();
BinaryNode p = this.root;while (p != null) {//访问当前结点
System.out.print(p.data + " ");//p的左孩子结点入队
if (p.left != null)
que.enqueue(p.left);//p的右孩子结点入队
if (p.right != null)
que.enqueue(p.right);//p指向出队结点,若队列空返回null
p =que.dequeue();
}
System.out.println();
}/*** 返回二叉树的结点个数*/@Overridepublic intcount() {returncount(root);
}/*** 返回以p结点为根的子树的结点个数
*
*@paramp
*@return
*/
private int count(BinaryNodep) {if (p == null) {return 0;
}return 1 + count(p.left) +count(p.right);
}/*** 返回二叉树的高度*/@Overridepublic intheight() {returnheight(root);
}/*** 返回以p结点为根的子树高度,后根次序遍历
*
*@paramp
*@return
*/
private int height(BinaryNodep) {if (p == null) {return 0;
}//返回左子树的高度
int lh =height(p.left);//返回右子树的高度
int rh =height(p.right);//当前子树高度为较高子树的高度加1
return (lh >= rh) ? lh + 1 : rh + 1;
}/*** 查找并返回首次出现的关键字key元素*/@OverridepublicT search(T key) {returnsearchNode(root, key).data;
}/*** 查找并返回首次出现的关键字为key元素结点
*
*@paramkey
*@return
*/
public BinaryNodesearchNode(T key) {returnsearchNode(root, key);
}/*** 在以p为根的子树中查找并返回首次出现的关键字为key元素结点,若未找到返回null,先根次序遍历
*
*@paramp
*@paramkey
*@return
*/
private BinaryNode searchNode(BinaryNodep, T key) {if (p == null || key == null)return null;//查找成功,返回找到结点
if(p.data.equals(key)) {returnp;
}//在左子树中查找,递归调用
BinaryNode find =searchNode(p.left, key);//若在左子树中未找到,怎继续在右子树中查找,递归调用
if (find == null) {
find=searchNode(p.right, key);
}//返回查找结果
returnfind;
}/*** 返回node结点的父母结点,若空树、未找到或node为根,则返回null*/@Overridepublic BinaryNode getParent(BinaryNodenode) {if (root == null || node == null || node ==root) {return null;
}returngetParent(root, node);
}/*** 在以p为根的子树中查找并返回node结点的父母结点
*
*@paramp
*@paramnode
*@return
*/
private BinaryNode getParent(BinaryNode p, BinaryNodenode) {if (p == null)return null;if (p.left == node || p.right ==node)returnp;
BinaryNode find =getParent(p.left, node);if (find == null) {
find=getParent(p.right, node);
}returnfind;
}/*** 插入元素x作为根结点,原根结点作为其左孩子*/@Overridepublic voidinsertRoot(T x) {this.root = new BinaryNode(x, this.root, null);
}/*** 插入元素x作为p结点的孩子,若leftChild为true,插入结点作为左孩子,否则作为右孩子 返回插入结点,若p == null,
* 则抛出空对象异常*/@Overridepublic BinaryNode insertChild(BinaryNode p, T x, booleanleftChild) {if (x == null)return null;if(leftChild) {//插入x结点作为p的左孩子,p原左孩子成为x的左孩子
p.left = new BinaryNode(x, p.left, null);returnp.left;
}//插入x结点作为p的右孩子,p原右孩子成为x的右孩子
p.right = new BinaryNode(x, null, p.right);returnp.right;
}/*** 删除p结点的左或右子树,若leftChild为true,删除左子树,否则删除右子树
*
* 若p == null,将抛出空对象异常*/@Overridepublic void removeChild(BinaryNode p, booleanleftChild) {if(leftChild)
p.left= null;elsep.right= null;
}/*** 删除二叉树的所有结点*/@Overridepublic voidremoveAll() {this.root = null;
}
@OverridepublicString toString() {returntoString(root);
}private String toString(BinaryNodep) {if (p == null) {return "";
}//递归调用
return p.data.toString() + " " + toString(p.left) +toString(p.right);
}/*** 以先根和中根序列够杂二叉树
*
*@paramprelist
*@paraminlist*/
publicBinaryTree(T[] prelist, T[] inlist) {this.root = create(prelist, inlist, 0, 0, prelist.length);
}private BinaryNode create(T[] prelist, T[] inlist, intpreStart,int inStart, intn) {
System.out.print("prelist: ");
print(prelist, preStart, n);
System.out.print(", inlist: ");
print(inlist, inStart, n);
System.out.println();if (n <= 0) {return null;
}//根结点值
T elem =prelist[preStart];//创建叶子结点
BinaryNode p = new BinaryNode(elem);int i = 0;//在中根序列中查找根值所在位置
while (i < n && elem.equals(inlist[inStart +i]))
i++;//创建左子树
p.left = create(prelist, inlist, preStart + 1, inStart, i);//创建右子树
p.right = create(prelist, inlist, preStart + 1, inStart + i + 1, n - 1
-i);returnp;
}private void print(T[] table, int start, intn) {for (int i = 0; i < n; i++) {
System.out.print(table[start+i]);
}
}/*** 以标明空子树的先根序列构造二叉树
*
*@paramprelist*/
publicBinaryTree(T[] prelist) {this.root =create(prelist);
}/*** 以标明空子树的先根序列构造一棵子二叉树,子的根值是prelist[i],返回所创建子树的根结点*/
private int i = 0;private BinaryNodecreate(T[] prelist) {
BinaryNode p = null;if (i
T elem=prelist[i];
i++;if (elem != null) {//创建叶子结点
p = new BinaryNode(elem);//创建p的左子树
p.left =create(prelist);//创建p的右子树
p.right =create(prelist);
}
}returnp;
}/*** 返回二叉树的广义表表示字符串
*
*@return
*/
publicString toGenListString() {return "二叉树的广义表表示:" + toGenListString(this.root) + "\n";
}/*** 返回以p结点为根的子二叉树的广义表表示字符串,递归方法
*
*@paramp
*@return
*/
private String toGenListString(BinaryNodep) {if (p == null)return "^";
String str=p.data.toString();//非叶结点,有子树
if (p.left != null || p.right != null)//递归调用
str += "(" + toGenListString(p.left) + ", "
+ toGenListString(p.right) + ")";returnstr;
}/*** 二叉树遍历的非递归算法
*
* 先根次序遍历二叉树的非递归算法*/
public voidpreOrderTraverse() {
System.out.print("先根次序遍历(非遍历)");//创建一个空栈
LinkedStack> stack = new LinkedStack>();
BinaryNode p = this.root;//p非空或栈非空时
while (p != null || !stack.isEmpty()) {if (p != null) {//方位结点
System.out.print(p.data + " ");//p结点入栈
stack.push(p);//进入左子树
p =p.left;
}else{//p指向出栈结点
p =stack.pop();//进入右子树
p =p.right;
}
}
System.out.println();
}/*** 中根次序遍历二叉树的非递归算法*/
public voidinOrderTraverse() {
System.out.print("中根次序遍历(非遍历) : ");
LinkedStack> stack = new LinkedStack>();
BinaryNode p = this.root;//p非空或栈非空时
while (p != null || !stack.isEmpty()) {if (p != null) {//p结点入栈
stack.push(p);//进入左结点
p =p.left;
}else{//p指向出栈结点
p =stack.pop();
System.out.print(p.data+ " ");//进入右子树
p =p.right;
}
}
System.out.println();
}/*** 遍历输出叶子结点*/
public voidleaf() {
leaf(root);
}private void leaf(BinaryNodep) {if (p != null) {if (p.left == null && p.right == null)
System.out.print(p.data.toString()+ " ");
leaf(p.left);
leaf(p.right);
}
}/*** 返回以p结点为根的子树的叶子结点个数
*
*@paramp
*@return
*/
public int countLeaf(BinaryNodep) {if (p == null) {return 0;
}if (p.left == null && p.right == null) {return 1;
}return countLeaf(p.left) +countLeaf(p.right);
}/*** 将首次出现的值为x的结点替换为y
*
*@paramx
*@paramy*/
public voidreplace(T x, T y) {
BinaryNode find =searchNode(x);if (find != null) {
find.data=y;
}
}/*** 将值为x的结点值全部替换为y
*
*@paramx
*@paramy*/
public voidreplaceAll(T x, T y) {if (x != null && y != null) {
replaceAll(root, x, y);
}
}/*** 在以p为根的子树中实现全部替换
*
*@paramp
*@paramx
*@paramy*/
private void replaceAll(BinaryNodep, T x, T y) {if (p != null) {if(p.data.equals(x)) {
p.data=y;
}
replaceAll(p.left, x, y);
replaceAll(p.right, x, y);
}
}/*** 后根次序遍历二叉树的非递归算法*/
public voidpostOrderTraverse() {
System.out.print("后根次序遍历(非递归): ");
LinkedStack> stack = new LinkedStack>();
BinaryNode p = this.root, front = null;while (p != null ||stack.isEmpty()) {if (p != null) {//p结点入栈
stack.push(p);//进入左子树
p =p.left;
}else{//从左子树返回p结点,p结点不出栈
p =stack.get();//p有右孩子,且右孩子没有被访问过
if (p.right != null && p.right !=front) {//进入右子树
p =p.right;
stack.push(p);//向左走
p =p.left;
}else{
p=stack.pop();
System.out.println(p.data+ "的所有祖先结点是:" +stack.toString());
front=p;//front 是p在后根遍历次序下的前驱结点
p = null;
}
}
}
System.out.println();
}/*** 返回x结点所在的层次,若空树或未查找到x返回-1
*
*@paramx
*@return
*/
public intgetLevel(T x) {//令根结点的层次为1
return getLevel(root, 1, x);
}/*** 在以p结点(层次为i)为根的子树中,求x结点所在的层次
*
*@paramp
*@parami
*@paramx
*@return
*/
private int getLevel(BinaryNode p, inti, T x) {//空树或查找不成功
if (p == null) {return -1;
}if(p.data.equals(x))returni;//在左子树查找
int level = getLevel(p.left, i + 1, x);if (level == -1) {//继续在右子树中查找
level = getLevel(p.right, i + 1, x);
}returnlevel;
}/*** 比较两棵二叉树是否相等
*
*@paramobj
*@return
*/@SuppressWarnings("unchecked")public booleanequals(Object obj) {return obj == this || obj instanceofBinaryTree&& equals(this.root, ((BinaryTree) obj).root);
}/*** 判断以p和q结点为根的两棵子树是否相等,递归方法
*@paramp
*@paramq
*@return
*/
private boolean equals(BinaryNode p, BinaryNodeq) {return p == null && q == null || p != null && q != null && p.data.equals(q.data) &&equals(p.left, q.left)&&equals(p.right, q.right);
}/*** 深拷贝,以已知的bitree构造二叉树
*@parambitree*/
public BinaryTree(BinaryTreebitree) {this.root =copy(bitree.root);
}/*** 复制以p为根的子二叉树,返回新建子二叉树的根结点
*@paramp
*@return
*/
private BinaryNode copy(BinaryNodep) {if (p == null)return null;
BinaryNode q = new BinaryNode(p.data);//复制左子树,递归调用
q.left =copy(p.left);//复制右子树,递归调用
q.right =copy(p.right);//返回建立子树的根结点
returnq;
}/*** 判断是否完全二叉树
*@return
*/
booleanisCompleteBinaryTree() {if (this.root == null)return true;
LinkedQueue> que = new LinkedQueue>();
que.enqueue(root);
BinaryNode p = null;while (!que.isEmpty()) {//p指向出对结点
p =que.dequeue();//p的非空孩子结点入队
if (p.left != null) {
que.enqueue(p.left);if (p.right != null) {//发现空子树,须检测队列中是否都是叶子结点
que.enqueue(p.right);
}else{break;
}
}else{if (p.right != null) {//p的左子树空而右子树不空
return false;
}else{//p是叶子,须检测队列中是否都是叶子结点
break;
}
}
}//检测队列中是否都是叶子结点
while(!que.isEmpty()) {
p=que.dequeue();//发现非叶子,确定不是
if (p.left != null || p.right != null) {return false;
}
}return true;
}
}