二叉树的定义与实现

/**
*

  • 二叉链式存储结构下的二叉树结点

*/
public class BiTreeNode {
public Object data;// 结点的数据元素

public BiTreeNode lchild, rchild; // 左右孩子

public BiTreeNode() {// 构造一个空结点
	this(null);
}

public BiTreeNode(Object data) {// 构造一棵左右孩子为空的结点
	this(data, null, null);
}

public BiTreeNode(Object data, BiTreeNode lchild, BiTreeNode rchild) {// 构造一棵数据元素和左右孩子都不为空的结点
	this.data = data;
	this.lchild = lchild;
	this.rchild = rchild;
}

}

/**
*
*二叉链式存储结构下的二叉树
*
*/


涉及链与队列部分参照博主的相应部分


import ch03.LinkQueue;
import ch03.LinkStack;

public class BiTree {

private BiTreeNode root;// 树的根结点

public BiTree() {// 构造一棵空树
	this.root = null;
}

public BiTree(BiTreeNode root) {// 构造一棵树
	this.root = root;
}

// 由先根遍历的数组和中根遍历的数组建立一棵二叉树
// 其中参数preOrder是整棵树的 先根遍历,inOrder是整棵树的中根遍历,preIndex是
// 先根遍历从preOrder字符串中的开始位置,inIndex是中根遍历从字符串inOrder中的开始位置,count表示树结点的个数
public BiTree(String preOrder, String inOrder, int preIndex, int inIndex,
		int count) {
	if (count > 0) {// 先根和中根非空
		char r = preOrder.charAt(preIndex);// 取先根字符串中的第一个元素作为根结点
		int i = 0;
		for (; i < count; i++)
			// 寻找根结点在中根遍历字符串中的索引
			if (r == inOrder.charAt(i + inIndex))
				break;

		root = new BiTreeNode(r);// 建立树的根结点
		root.lchild=new BiTree(preOrder, inOrder, preIndex + 1, inIndex,
				i).root;// 建立树的左子树
		root.rchild=new BiTree(preOrder, inOrder, preIndex + i + 1,
				inIndex + i + 1, count - i - 1).root;// 建立树的右子树
	}
}

// 由标明空子树的先根遍历序列建立一棵二叉树
private static int index = 0;// 用于记录preStr的索引值

public BiTree(String preStr) {
	char c = preStr.charAt(index++);// 取出字符串索引为index的字符,且index增1
	if (c != '#') {// 字符不为#
		root = new BiTreeNode(c);// 建立树的根结点
		root.lchild=new BiTree(preStr).root;// 建立树的左子树
		root.rchild=new BiTree(preStr).root;// 建立树的右子树
	} else
		root = null;
}

// 先根遍历二叉树基本操作的递归算法
public void preRootTraverse(BiTreeNode T) {
	if (T != null) {
		System.out.print(T.data); // 访问根结点
		preRootTraverse(T.lchild);// 访问左子树
		preRootTraverse(T.rchild);// 访问右子树
	}
}

// 先根遍历二叉树基本操作的非递归算法
public void preRootTraverse() {
	BiTreeNode T = root;
	if (T != null) {
		LinkStack S = new LinkStack();// 构造栈
		S.push(T);// 根结点入栈
		while (!S.isEmpty()) {
			T = (BiTreeNode) S.pop();// 移除栈顶结点,并返回其值
			System.out.print(T.data); // 访问结点
			while (T != null) {
				if (T.lchild != null) // 访问左孩子
					System.out.print(T.lchild.data); // 访问结点

				if (T.rchild != null)// 右孩子非空入栈
					S.push(T.rchild);

				T = T.lchild;
			}
		}
	}
}

// 中根遍历二叉树基本操作的递归算法
public void inRootTraverse(BiTreeNode T) {
	if (T != null) {
		inRootTraverse(T.lchild);// 访问左子树
		System.out.print(T.data); // 访问根结点
		inRootTraverse(T.rchild);// 访问右子树
	}
}

// 中根遍历二叉树基本操作的非递归算法
public void inRootTraverse() {
	BiTreeNode T = root;
	if (T != null) {
		LinkStack S = new LinkStack();// 构造链栈
		S.push(T); // 根结点入栈
		while (!S.isEmpty()) {
			while (S.peek() != null)
				// 将栈顶结点的所有左孩子结点入栈
				S.push(((BiTreeNode) S.peek()).lchild);
			S.pop(); // 空结点退栈
			if (!S.isEmpty()) {
				T = (BiTreeNode) S.pop();// 移除栈顶结点,并返回其值
				System.out.print(T.data); // 访问结点
				S.push(T.rchild);// 结点的右孩子入栈
			}
		}
	}
}

// 后根遍历二叉树基本操作的递归算法
public void postRootTraverse(BiTreeNode T) {
	if (T != null) {
		postRootTraverse(T.lchild);// 访问左子树
		postRootTraverse(T.rchild);// 访问右子树
		System.out.print(T.data); // 访问根结点
	}
}

// 后根遍历二叉树基本操作的非递归算法
public void postRootTraverse() {
	BiTreeNode T = root;
	if (T != null) {
		LinkStack S = new LinkStack();// 构造链栈
		S.push(T); // 根结点进栈
		Boolean flag;// 访问标记
		BiTreeNode p = null;// p指向刚被访问的结点
		while (!S.isEmpty()) {
			while (S.peek() != null)
				// 将栈顶结点的所有左孩子结点入栈
				S.push(((BiTreeNode) S.peek()).lchild);
			S.pop(); // 空结点退栈
			while (!S.isEmpty()) {
				T = (BiTreeNode) S.peek();// 查看栈顶元素
				if (T.rchild == null || T.rchild == p) {
					System.out.print(T.data); // 访问结点
					S.pop();// 移除栈顶元素
					p = T;// p指向刚被访问的结点
					flag = true;// 设置访问标记
				} else {
					S.push(T.rchild);// 右孩子结点入栈
					flag = false;// 设置未被访问标记
				}
				if (!flag)
					break;
			}
		}
	}
}

// 层次遍历二叉树基本操作的算法(自左向右)
public void levelTraverse() {
	BiTreeNode T = root;
	if (T != null) {
		LinkQueue L = new LinkQueue();// 构造队列
		L.offer(T);// 根结点入队列
		while (!L.isEmpty()) {
			T = (BiTreeNode) L.poll();
			System.out.print(T.data); // 访问结点
			if (T.lchild != null)// 左孩子非空,入队列
				L.offer(T.lchild);
			if (T.rchild != null)// 右孩子非空,入队列
				L.offer(T.rchild);
		}
	}

}

public BiTreeNode getRoot() {
	return root;
}

public void setRoot(BiTreeNode root) {
	this.root = root;
}

// 统计叶结点数目
public int countLeafNode(BiTreeNode T) {
	int count = 0;
	if (T != null) {
		if (T.lchild == null && T.rchild == null) {
			++count;// 叶结点个数加1
		} else {
			count += countLeafNode(T.lchild); // 加上左子树上叶结点的个数
			count += countLeafNode(T.rchild);// 加上右子树上叶结点的个数
		}
	}
	return count;
}

// 统计结点的数目
public int countNode(BiTreeNode T) {
	int count = 0;
	if (T != null) {
		++count;// 结点的个数加1
		count += countNode(T.lchild); // 加上左子树上结点的个数
		count += countNode(T.rchild);// 加上右子树上结点的个数
	}
	return count;
}

}
/**
*

  • 为了调试的需要,创建一棵树

*/
public class BiTreeCreator {

// 初始化一棵树,并返回其根结点
public BiTree createBiTree() {
	BiTreeNode A = new BiTreeNode('A');
	BiTreeNode B = new BiTreeNode('B');
	BiTreeNode C = new BiTreeNode('C');
	BiTreeNode D = new BiTreeNode('D');
	BiTreeNode E = new BiTreeNode('E');
	BiTreeNode F = new BiTreeNode('F', null, A);
	BiTreeNode G = new BiTreeNode('G', B, null);
	BiTreeNode H = new BiTreeNode('H', G, null);
	BiTreeNode I = new BiTreeNode('I', null, E);
	BiTreeNode J = new BiTreeNode('J', D, I);
	BiTreeNode K = new BiTreeNode('K', F, H);
	BiTreeNode L = new BiTreeNode('L', C, J);
	BiTreeNode root = new BiTreeNode('M', K, L);
	return new BiTree(root);
}

public BiTree createBiTree2() {
	BiTreeNode B = new BiTreeNode('B');
	BiTreeNode C = new BiTreeNode('C');
	BiTreeNode D = new BiTreeNode('D');
	BiTreeNode E = new BiTreeNode('E');
	BiTreeNode F = new BiTreeNode('F', null, null);
	BiTreeNode G = new BiTreeNode('G', B, null);
	BiTreeNode H = new BiTreeNode('H', G, null);
	BiTreeNode I = new BiTreeNode('I', null, E);
	BiTreeNode J = new BiTreeNode('J', D, I);
	BiTreeNode K = new BiTreeNode('K', F, H);
	BiTreeNode L = new BiTreeNode('L', C, J);
	BiTreeNode root = new BiTreeNode('M', K, L);
	return new BiTree(root);
}

}
/**
*

  • 调试二叉链式存储结构下的二叉树的各操作

*/
public class DebugBiTree {

public BiTree createBiTree() {
	BiTreeNode d = new BiTreeNode('D');
	BiTreeNode g = new BiTreeNode('G');
	BiTreeNode h = new BiTreeNode('H');
	BiTreeNode e = new BiTreeNode('E', g, null);
	BiTreeNode b = new BiTreeNode('B', d, e);
	BiTreeNode f = new BiTreeNode('F', null, h);
	BiTreeNode c = new BiTreeNode('C', f, null);
	BiTreeNode a = new BiTreeNode('A', b, c);
	return new BiTree(a);
	// 创建根结点为a的二叉树,其中二叉树类BitTree的定义紧接在DebugBiTree类的后面给出
}

public static void main(String[] args) {
	DebugBiTree debugBiTree = new DebugBiTree();
	BiTree biTree = debugBiTree.createBiTree();
	BiTreeNode root = biTree.getRoot();// 取得树的根结点

	// 调试先根遍历

	System.out.print("(递归)先根遍历序列为:");
	biTree.preRootTraverse(root);
	System.out.println(); // 输出换行
	System.out.print("(非递归)先根遍历序列为:");
	biTree.preRootTraverse();
	System.out.println();
	// 调试中根遍历
	System.out.print("(递归)中根遍历序列为:");
	biTree.inRootTraverse(root);
	System.out.println();
	System.out.print("(非递归)中根遍历序列为:");
	biTree.inRootTraverse();
	System.out.println();
	// 调试后根遍历
	System.out.print("(递归)后根遍历序列为:");
	biTree.postRootTraverse(root);
	System.out.println();
	System.out.print("(非递归)后根遍历序列为:");
	biTree.postRootTraverse();
	System.out.println();
	// 调试层次遍历
	System.out.print("层次遍历序列为:");
	biTree.levelTraverse();
	System.out.println();
}

}
// 运行结果:
// (递归)先根遍历序列为:ABDEGCFH
// (非递归)先根遍历序列为:ABDEGCFH
// (递归)中根遍历序列为:DBGEAFHC
// (非递归)中根遍历序列为:DBGEAFHC
// (递归)后根遍历序列为:DGEBHFCA
// (非递归)后根遍历序列为:DGEBHFCA
// 层次遍历序列为:ABCDEFGH

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值