目录
通过数组实现二叉树
通过链表实现二叉树
排序二叉树的实现
通过数组实现二叉树
该实现方式只能用于完全二叉树,因为如果是普通二叉数的话,数组中会出现空隙,会导致空间的利用率会降低。
实现思路:
因为假设一个父节点的下标为parentIndex,那么他的左子节点的下标就为2parentIndex,他的右子节点的下标就为2parentIndex+1。
所以想要获取一个左子节点时只需将她父节点的下标通过<<1即可(相当于* 2)获得左子节点的下标,获取右子节点时与之相同,不过在<<1的同时在+1。
而将一个数组直接转换为二叉树只需将数组下标向右移一位即可,下标从1开始。
/**
* @author CC
* @version 1.0
* @since2023/10/7
* 使用数组实现二叉树
*/
public class BinaryToArrayTree<E> {
private Object[] elementData = null;
/**
* 有参构造 直接将一个数组变为二叉树
* @param elements
*/
public BinaryToArrayTree(E[] elements) {
elementData = new Object[elements.length + 1];
for (int i = 0, index = 1; i < elements.length; i++, index++) {
elementData[index] = elements[i];
}
}
/**
* 获取该下标的值
* @param index
* @return
*/
public E get(int index){
return (E) elementData[index];
}
/**
* 获取该下标的左子节点的值
* @param index
* @return
* @throws Exception
*/
public E left(int index) throws Exception {
if ((index<<1)>=elementData.length){
throw new Exception("左孩子节点不存在!");
}
return (E) elementData[index<<1];
}
/**
* 获取该下标的右子节点的值
* @param index
* @return
* @throws Exception
*/
public E right(int index) throws Exception {
if (((index<<1)+1)>=elementData.length){
throw new Exception("右孩子节点不存在!");
}
return (E) elementData[(index<<1)+1];
}
}
测试
public class BATest {
public static void main(String[] args) throws Exception {
String[] array ={"A","B","C","D","E","F","G","H"};
BinaryToArrayTree<String> binaryTree =new BinaryToArrayTree<>(array);
System.out.println("下标为1的节点值"+binaryTree.get(1));
System.out.println("下标为1的左子节点值"+binaryTree.left(1));
System.out.println("下标为1的右子节点值"+binaryTree.right(1));
}
}
测试结果
通过链表实现二叉树
/**
* @author CC
* @version 1.0
* @since2023/10/7
* 使用链表实现二叉树
*/
public class BinaryToListTree<E> {
TreeNode<E> root;//根节点
public BinaryToListTree(E val) {
root = new TreeNode<E>(val);
}
/**
* 存入左节点
* @param parent 父节点
* @param val 左节点的值
* @return
*/
public TreeNode<E> left(TreeNode<E> parent, E val) {
TreeNode<E> newNode = new TreeNode<>(val);
parent.left = newNode;
return newNode;
}
/**
* 存入右节点
* @param parent 父节点
* @param val 右节点的值
* @return
*/
public TreeNode<E> right(TreeNode<E> parent, E val) {
TreeNode<E> newNode = new TreeNode<>(val);
parent.right = newNode;
return newNode;
}
/**
* 先序遍历
* @param root 根节点
*/
public void preOrder(TreeNode root){
if (root==null){
return;
}
System.out.print(root.data);
preOrder(root.left);
preOrder(root.right);
}
/**
* 中序遍历
* @param root 根节点
*/
public void inOrder(TreeNode root){
if (root==null){
return;
}
inOrder(root.left);
System.out.print(root.data);
inOrder(root.right);
}
/**
* 后序遍历
* @param root 根节点
*/
public void postOrder(TreeNode root){
if (root==null){
return;
}
postOrder(root.left);
postOrder(root.right);
System.out.print(root.data);
}
/**
* 层序遍历
* @param root 根节点
*/
public void levelOrder(TreeNode root){
if (root ==null){
return;
}
Queue<TreeNode> queue =new LinkedList<>();
queue.offer(root);
while (true){
TreeNode cur = queue.poll();
if (cur==null){
return;
}
System.out.print(cur.data);
if (cur.left!=null){
queue.offer(cur.left);
}
if (cur.right!=null){
queue.offer(cur.right);
}
}
}
/**
* 节点类
* @param <E>
*/
public static class TreeNode<E> {
E data;//数据
TreeNode<E> left;//左节点
TreeNode<E> right;//右节点
public TreeNode() {
}
public TreeNode(E val) {
this.data = val;
}
}
}
测试
public class BLTest {
public static void main(String[] args) {
BinaryToListTree<String> tree =new BinaryToListTree<>("A");
//将B C 分别存入A 的左右节点
BinaryToListTree.TreeNode<String> b= tree.left(tree.root, "B");
BinaryToListTree.TreeNode<String> c= tree.right(tree.root, "C");
//将D E 分别存入B 的左右节点
BinaryToListTree.TreeNode<String> d= tree.left(b, "D");
BinaryToListTree.TreeNode<String> e= tree.right(b, "E");
//将F G 分别存入C 的左右节点
BinaryToListTree.TreeNode<String> f= tree.left(c, "F");
BinaryToListTree.TreeNode<String> g= tree.right(c, "G");
System.out.println("根节点:"+tree.root.data);
System.out.println("根节点的左子节点:"+tree.root.left.data);
System.out.println("根节点的右子节点:"+tree.root.right.data);
System.out.println("根节点的左子节点的左子节点:"+tree.root.left.left.data);
System.out.println("根节点的左子节点的右子节点:"+tree.root.left.right.data);
System.out.println("根节点的右子节点的左子节点:"+tree.root.right.left.data);
System.out.println("根节点的右子节点的右子节点:"+tree.root.right.right.data);
System.out.print("前序遍历:");
tree.preOrder(tree.root);
System.out.println();
System.out.print("中序遍历:");
tree.inOrder(tree.root);
System.out.println();
System.out.print("后序遍历:");
tree.postOrder(tree.root);
System.out.println();
System.out.print("层序遍历:");
tree.levelOrder(tree.root);
}
}
测试结果
排序二叉树的实现
实现思路:
二叉排序数他的实现思路是父节点的左子节点一定小于父节点,而父节点的右子节点一定大于父节点,所以排序二叉树的中序遍历就是就是该二叉树节点从小到大的排序。他的最大值就是根节点的最右子节点,而最小值就是根节点的最左子节点。
/**
* 二叉排序树
* @author CC
* @version 1.0
* @since2023/10/8
*/
public class BinarySortTree {
TreeNode root;//根节点
/**
* 初始化方法
* @param arr
*/
public void init(int[] arr){
for (int i : arr) {
insert(new TreeNode(i));
}
}
/**
* 中序遍历
* @param node
*/
public void inOrder(TreeNode node){
if (node==null){
return;
}
inOrder(node.left);
System.out.print(node.data+" ");
inOrder(node.right);
}
/**
* 插入节点
* @param newNode
*/
public void insert(TreeNode newNode){
TreeNode currentNode =this.root;//查找过程中的当前节点
TreeNode parent =null;//插入节点的父节点
//查找新节点的插入位置
while (currentNode !=null){
parent =currentNode;
if (newNode.data<currentNode.data){
currentNode =currentNode.left;
}else {
currentNode = currentNode.right;
}
}
//查找到的最终节点作为新节点的父节点
newNode.parent =parent;
//如果该该树为空 没有父节点
if (parent==null){
this.root =newNode;
}else {
if (newNode.data<parent.data){
parent.left =newNode;
}else {
parent.right=newNode;
}
}
}
/**
* 通过节点值和节点查找
* @param currentNode
* @param data
* @return
*/
private TreeNode search(TreeNode currentNode,Integer data){
if (currentNode==null){
return null;
}
if (data<currentNode.data){
return search(currentNode.left,data);
}else if (data>currentNode.data){
return search(currentNode.right,data);
}else {
return currentNode;
}
}
/**
* 通过节点值查找查找 默认从根节点开始查找
* @param data
* @return
*/
public TreeNode search(Integer data){
TreeNode resultNode =search(this.root,data);
return resultNode;
}
/**
* 查找最大值
* @param currentNode
* @return
*/
public TreeNode max(TreeNode currentNode){
if (currentNode==null){
return null;
}
TreeNode parent =null;
while (currentNode!=null){
parent =currentNode;
currentNode=currentNode.right;
}
return parent;
}
/**
* 查找最小值
* @param currentNode
* @return
*/
public TreeNode min(TreeNode currentNode){
if (currentNode ==null){
return null;
}
TreeNode parent =null;
while (currentNode!=null){
parent=currentNode;
currentNode =currentNode.left;
}
return parent;
}
/**
* 节点类
*/
static class TreeNode{
Integer data; //节点数据
TreeNode left; //左子节点
TreeNode right; //右子节点
TreeNode parent; //父节点
public TreeNode(){
}
public TreeNode(Integer val){
this.data =val;
}
}
}
测试
public class BSTest {
public static void main(String[] args) {
BinarySortTree bst =new BinarySortTree();
bst.init(new int[] {2,8,6,9,31,3,5,21,7,14});
System.out.print("中序遍历:");
bst.inOrder(bst.root);
System.out.println();
BinarySortTree.TreeNode node = bst.search(2);
System.out.println("查找2:"+node.data);
System.out.println("最大值:"+bst.max(bst.root).data);
System.out.println("最小值:"+bst.min(bst.root).data);
}
}
测试结果