二叉树的链式存储
节点类
package 二叉树的链式存储;
public class TreeNode {
// 节点的权
int value;
// 左儿子
TreeNode leftNode;
// 右儿子
TreeNode rightNode;
public TreeNode(int value) {
this.value = value;
}
// 设置左儿子
public void setLeftNode(TreeNode leftNode) {
this.leftNode = leftNode;
}
// 设置右儿子
public void setRightNode(TreeNode rightNode) {
this.rightNode = rightNode;
}
/**
* 先序遍历
*/
public void preOrder() {
// 访问根节点
System.out.print(value + " ");
// 遍历左子树
if (leftNode != null) {
leftNode.preOrder();
}
// 遍历右子树
if (rightNode != null) {
rightNode.preOrder();
}
}
/**
* 中序遍历
*/
public void inOrder() {
// 先遍历左子树
if (leftNode != null) {
leftNode.inOrder();
}
// 访问根结点
System.out.print(value + " ");
// 然后遍历右子树
if (rightNode != null) {
rightNode.inOrder();
}
}
/**
* 后序遍历
*/
public void postOrder() {
//遍历左子树
if(leftNode != null) {
leftNode.postOrder();
}
//遍历右子树
if(rightNode != null) {
rightNode.postOrder();
}
//访问根节点
System.out.print(value + " ");
}
/**
* 先序查找
* @param i
* @return
*/
public TreeNode preSearch(int i) {
TreeNode target = null;
//对比当前根节点的值
if(this.value == i) {
return this;
}
//当前节点的值不是要查找的节点
else {//查找其儿子
//查到左儿子
if(leftNode != null) {
target = leftNode.preSearch(i);
}
//如果不为空则说明已经找到,直接返回,否则继续查询右儿子
if(target != null) {
return target;
}
//查找右儿子
if(rightNode != null) {
target = rightNode.preSearch(i);
}
}
return target;
}
/**
* 删除子树
* @param i
*/
public void deleteSubTree(int i) {
TreeNode parent = this;
//判断左儿子
if(parent.leftNode != null && parent.leftNode.value == i) {
parent.leftNode = null;
return;
}
//判断右儿子
if(parent.rightNode != null && parent.rightNode.value == i) {
parent.rightNode = null;
return;
}
//递归检查并删除左儿子
parent = leftNode;
if(parent != null) {
parent.deleteSubTree(i);
}
//递归检查并删除右儿子
parent = rightNode;
if(parent != null) {
parent.deleteSubTree(i);
}
}
}
树类
package 二叉树的链式存储;
public class BinaryTree {
//根结点
TreeNode root;
//设置根结点
public void setRoot(TreeNode root) {
this.root = root;
}
//获取根结点
public TreeNode getRoot() {
return root;
}
//先序遍历
public void preOrder() {
root.preOrder();
}
//中序遍历
public void inOrder() {
root.inOrder();
}
//后序遍历
public void postOrder() {
root.postOrder();
}
//先序查找
public TreeNode preSearch(int i) {
return root.preSearch(i);
}
//删除子树
public void deleteSubTree(int i) {
if(root.value == i) {
root = null;
return;
}
else {
root.deleteSubTree(i);
}
}
}
测试
@Test
public void testBinaryTree() {
// 创建一颗树:树里面都是节点组成的,通过设置节点的孩子节点来壮大
BinaryTree tree = new BinaryTree();
// 创建一个根结点
TreeNode root = new TreeNode(1);
tree.setRoot(root);
//创建左节点
TreeNode rootL = new TreeNode(2);
//创建右节点
TreeNode rootR = new TreeNode(3);
//将左节点作为根节点的左孩子节点
root.setLeftNode(rootL);
//将右节点最为根结点的右孩子节点
root.setRightNode(rootR);
//为第二层的左节点创建两个子节点
rootL.setLeftNode(new TreeNode(4));
rootL.setRightNode(new TreeNode(5));
//为第二层的右节点创建两个子节点
rootR.setLeftNode(new TreeNode(6));
rootR.setRightNode(new TreeNode(7));
//遍历二叉树
//1.先序遍历
tree.preOrder();
System.out.println();
//2.中序遍历
tree.inOrder();
System.out.println();
//3.后序遍历
root.postOrder();
//查找
//1.先序查找
TreeNode result = tree.preSearch(3);
System.out.println(result==rootR);
//删除一个子树
tree.deleteSubTree(3);
tree.preOrder();
}
二叉树的顺序存储
- 二叉树顺序存储的几个重要性质:
(1)第n个元素的左孩子节点为:2n+1。
(2)第n个元素的右孩子节点为:2n+2。
(3)第n个元素的父节点为:(n-1)/2。
package 二叉树的顺序存储;
public class ArrayBinaryTree {
int[] data;
public ArrayBinaryTree(int[] data) {
this.data = data;
}
public void preOrder() {
preOrder(0);
}
//先序遍历
public void preOrder(int index) {
if(data == null || data.length == 0) {
return;
}
//先遍历当前节点的内容
System.out.println(data[index]);
//遍历左子树 2n+1;数组是从0开始排序的,所以到data.length的前一个位置
if((2*index + 1) < data.length) {
preOrder(2*index+1);
}
//遍历右子树 2n+2
if((2*index+2) < data.length) {
preOrder(2*index+2);
}
}
}
测试
@Test
public void testArrayBinaryTree() {
int[] arr = new int[] {1,2,3,4,5,6,7};
ArrayBinaryTree btree = new ArrayBinaryTree(arr);
//前序遍历
btree.preOrder();
}