本文主要实现二叉树的简单功能:
(1)二叉树的生成
(2)二叉树的遍历:前序遍历,中序遍历,后序遍历,层次遍历
(3)二叉树的删除
(3)判断节点是否存在的功能
package ds.tree;
import ds.link.Node;
import java.util.LinkedList;
import java.util.Queue;
/**
* @author : cuantianhou 2019/12/17
*/
public class BinaryTree <T extends Comparable<T>>{
private Node<T> root;
private int capacity = 0;
public T insert(T data){
/**
* Step1: 如果该节点为空,将该节点设置为根节点,父节点为空,返回出入值
*
* */
capacity++;
if(root == null) {
root = new Node<T>(data,null);
return root.data;
}
/**
* Step2:从根节点遍历,插入节点比当前节点小,把当前节点设置为左子节点,然后与左子比较,
* 插入节点比当前节点大,把当前节点设置为右子节点,然后与右子比较,插入节点和当前节点相等
* 覆盖并返回当前值
**/
//父节点
Node<T> parent = root;
//与父节点比较的结果
int compareResult = 0;
//临时节点
Node<T> temp = root;
while(temp != null){
parent = temp;
compareResult = temp.data.compareTo(data);
if(compareResult == 0){
capacity--;
return temp.data = data;
}else if(compareResult > 0){
temp = temp.left;
}else{
temp = temp.right;
}
}
/** Step3 遍历结束,创建新的节点,看插入值和父节点值的比较结果,
*返回插入值
*/
Node<T> insertNode = new Node<T>(data,parent);
if(compareResult > 0){
parent.left = insertNode;
}else {
parent.right = insertNode;
}
return insertNode.data;
}
/**
* 返回根节点
* @return
*/
public Node<T> getRoot(){
return root;
}
public int getCapacity(){
return capacity;
}
/**
* 判断是否为空
* @return
*/
public boolean isEmpty(){
return capacity == 0;
}
/**
* 是否包含某一个元素
* @param data 数据量
* @return
*/
public boolean contains(T data){
return getNode(data,root) != null;
}
/**
* 判断该值是否存在树中
* @param item 项
*
* @return
*/
public Node<T> getNode(T item, Node<T> node){
if(node == null) {return null;}
int compareResult = node.data.compareTo(item);
if(compareResult > 0) { return getNode(item,node.left);}
if(compareResult < 0) { return getNode(item,node.right);}
return node;
}
/**
* 删除二叉树的节点
* @param item 节点数据
* @return
*/
public boolean remove(T item){
Node<T> searchNode = getNode(item,root);
//如果不存在,返回false
if(searchNode == null) return false;
Node<T> parentNode = searchNode.parent;
//容量减1
capacity--;
/**
* case 1: 左右都没有孩子
*/
if(searchNode.left == null && searchNode.right == null){
if(searchNode == root) {
root = null;
gcHelper(searchNode);
return true;
}
if(parentNode.right == searchNode){
parentNode.right = null;
gcHelper(searchNode);
return true;
}
if(parentNode.left == searchNode){
parentNode.left = null;
gcHelper(searchNode);
return true;
}
}
/**
* case2:只有左节点
*/
if(searchNode.right == null){
Node<T> leftNode = searchNode.left;
if(searchNode == root){
leftNode.parent = null;
root = leftNode;
gcHelper(searchNode);
return true;
}
if(parentNode.left == searchNode){
parentNode.left = leftNode;
}else{
parentNode.right = leftNode;
}
leftNode.parent = parentNode;
gcHelper(searchNode);
return true;
}
/**
* case3:只有右节点
*/
if(searchNode.left == null){
Node<T> rightNode = searchNode.right;
if(searchNode == root){
rightNode.parent = null;
root = rightNode;
gcHelper(searchNode);
return true;
}
if(parentNode.left == searchNode){
parentNode.left = rightNode;
}else{
parentNode.right = rightNode;
}
rightNode.parent = parentNode;
gcHelper(searchNode);
return true;
}
/**
* case4:有左右节点,关键是找到中继后续节点
*/
Node<T> targetNode = getTargetNode(searchNode);
if(searchNode.right == targetNode){
targetNode.parent = searchNode.parent;
searchNode.parent.right = targetNode;
}else{
searchNode.right.parent = searchNode.parent;
searchNode.parent.right = searchNode.right;
}
targetNode.left = searchNode.left;
gcHelper(searchNode);
return true;
}
/**
* gc回收
* @param deleteNode
*/
private void gcHelper(Node<T> deleteNode){
deleteNode.parent = null;
deleteNode.left = null;
deleteNode.right = null;
}
/**
* 获取中继后续节点
* @param searchNode 删除的节点
* @return
*/
public Node<T> getTargetNode(Node<T> searchNode){
Node<T> temp = searchNode.right;
while(temp.left != null){
temp = temp.left;
}
return temp;
}
/**
* 前序遍历 根左右
*/
public void preTransfer(Node<T> node){
if(node != null){
System.out.print(node.data+",");
preTransfer(node.left);
preTransfer(node.right);
}
}
/**
* 中序比遍历 左根右
* @param node
*/
public void midTransfer(Node<T> node){
if(node != null){
midTransfer(node.left);
System.out.print(node.data+",");
midTransfer(node.right);
}
}
/**
* 后序遍历 左右根
* @param node
*/
public void postTransfer(Node<T> node){
if(node != null){
postTransfer(node.left);
postTransfer(node.right);
System.out.print(node.data+",");
}
}
/**
* 层次遍历
* @param node
*/
public void levelTransfer(Node<T> node){
// Step1:看根节点是否为空,根节点不空,输出根节点的数据
// Step2: 判断左右的节点是否为空,不空,记录节点信息,进行下次判断
// Step3: 队列为空时退出循环
if(null == node) return;
LinkedList<Node<T>> levelNode = new LinkedList<>();
levelNode.add(node);
while(true) {
int size = levelNode.size();
if (size != 0) {
for (int i = 0; i < size; i++) {
Node<T> tempNode = levelNode.poll();
System.out.print(tempNode.data + ",");
if (tempNode.left != null) {
levelNode.add(tempNode.left);
}
if (tempNode.right != null) {
levelNode.add(tempNode.right);
}
}
}else {
break;
}
}
}
/**
* 清空树
*/
public void clear(){
clear(root);
root = null;
}
/**
* 清空树
* @param node 节点
*/
private void clear(Node<T> node){
if(node != null){
clear(node.left);
node.left = null;
clear(node.right);
node.right= null;
}
}
/**
* 节点的数据结构
* @param <T>
*/
private static final class Node <T extends Comparable<T>>{
private T data;
private Node left;
private Node right;
private Node parent;
public Node(T data,Node parent){
this.data = data;
this.parent = parent;
}
}
}
测试程序:
package ds.tree;
/**
* @author : cuantianhou 2019/12/18
*/
public class MainApplication {
public static void main(String[] args) {
BinaryTree<Integer> binaryTree = new BinaryTree<>();
//放数据
binaryTree.insert(73);
binaryTree.insert(22);
binaryTree.insert(532);
binaryTree.insert(62);
binaryTree.insert(72);
binaryTree.insert(243);
binaryTree.insert(42);
binaryTree.insert(3);
binaryTree.insert(12);
binaryTree.insert(52);
System.out.println("size: " + binaryTree.getCapacity());
binaryTree.insert(52);
System.out.println("添加相同元素后的size: " + binaryTree.getCapacity());
//判断数据是否存在
System.out.println("数据是否存在:" + binaryTree.contains(12));
//中序遍历
System.out.print("中序遍历结果: ");
binaryTree.midTransfer(binaryTree.getRoot());
System.out.println();
//前序遍历
System.out.print("前遍历结果: ");
binaryTree.preTransfer(binaryTree.getRoot());
System.out.println();
//后序遍历
System.out.print("后续遍历结果: ");
binaryTree.postTransfer(binaryTree.getRoot());
System.out.println();
//层次遍历
System.out.print("层次遍历结果: ");
binaryTree.levelTransfer(binaryTree.getRoot());
//删除数据
System.out.println();
binaryTree.remove(3);
//后序遍历
System.out.print("后续遍历结果: ");
binaryTree.postTransfer(binaryTree.getRoot());
System.out.println();
System.out.println("删除数据后判断是否存在:" + binaryTree.contains(3));
//清空二叉树
binaryTree.clear();
System.out.print("清空数据后中序遍历: ");
binaryTree.midTransfer(binaryTree.getRoot());
}
}
测试结果:
参考文章: