java深拷贝二叉树_数据结构学习----二叉树(Java实现)

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;

}

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值