创建一个TreeNode类,定义根节点和左右孩子节点以及节点的值value并获取get set方法。
1.树的插入(直接插入)
java
public void insert(int value) {
//创建一个节点
TreeNode node = new TreeNode(value);
//如果root是null,直接插入
if(root==null) {
root = node;
return;
}
//定义一个游标遍历整颗二叉树
TreeNode index = root;
//定义游标指向index的前一个地址
TreeNode pre = null;
while(true) {
pre = index;
if(index.getValue()<node.getValue()) {
//index游标往右走
index=index.getRightTreeNode();
if(index==null) {
//插入数据
pre.setRightTreeNode(node);
return;
}
}else {
//index游标往左走
index=index.getLeftTreeNode();
if(index==null) {
//插入数据
pre.setLeftTreeNode(node);
return;
}
}
}
}
2.树的插入(递归插入)
java
public void insertDigui(TreeNode treeNode,int value) {
//创建一个节点
TreeNode node = new TreeNode(value);
//如果root是null,直接插入
if(root==null) {
root = node;
return;
}
if(treeNode.getValue()>value) {
//在左边插入
if(treeNode.getLeftTreeNode()==null) {
treeNode.setLeftTreeNode(node);
return;
}
//向左递归
insertDigui(treeNode.getLeftTreeNode(), value);
}else {
//在右边插入
if(treeNode.getRightTreeNode()==null) {
treeNode.setRightTreeNode(node);
return;
}
//向右边递归
insertDigui(treeNode.getRightTreeNode(), value);
}
}
3.先序遍历(父---左---右)
java
public void beforOrder(TreeNode treeNode) {
if(treeNode==null) {
return;
}
System.out.print(treeNode.getValue()+" ");
beforOrder(treeNode.getLeftTreeNode());
beforOrder(treeNode.getRightTreeNode());
}
4.中序遍历(左---父---右)
java
public void inOrder(TreeNode treeNode) {
if(treeNode==null) {
return;
}
inOrder(treeNode.getLeftTreeNode());
System.out.print(treeNode.getValue()+" ");
inOrder(treeNode.getRightTreeNode());
}
5.后序遍历 (左---右---父)
java
public void afterOrder(TreeNode treeNode) {
if(treeNode==null) {
return;
}
afterOrder(treeNode.getLeftTreeNode());
afterOrder(treeNode.getRightTreeNode());
System.out.print(treeNode.getValue()+" ");
}
6.广度优先遍历(从根节点一次往下一层一层遍历)
java
public void levelOrder(TreeNode treeNode) {
LinkedList<TreeNode> queue = new LinkedList<>();
if(treeNode!=null) {
queue.add(treeNode);
}
while(!queue.isEmpty()) {
treeNode = queue.remove();
System.out.print(treeNode.getValue()+" ");
if(treeNode.getLeftTreeNode()!=null) {
queue.add(treeNode.getLeftTreeNode());
}
if(treeNode.getRightTreeNode()!=null) {
queue.add(treeNode.getRightTreeNode());
}
}
}
7.查询
java
public TreeNode find(int value) {
if(root==null) {
return null;
}
//定义index游标遍历
TreeNode index = root;
while(index!=null) {
if(index.getValue()==value) {
return index;
}else if(index.getValue()>value) {
index=index.getLeftTreeNode();
}else {
index=index.getRightTreeNode();
}
}
return null;
}
8.查找父亲节点
java
public TreeNode findParentNode(int value,TreeNode treeNode) {
if(treeNode==null) {
return null;
}
//判断当前节点是不是目标节点的父节点
if(treeNode.getLeftTreeNode()!=null && treeNode.getLeftTreeNode().getValue()==value ) {
return treeNode;
}else if(treeNode.getRightTreeNode()!=null && treeNode.getRightTreeNode().getValue()==value) {
return treeNode;
}else if(value>treeNode.getValue()) {
return findParentNode(value, treeNode.getRightTreeNode());
}else if(value<treeNode.getValue()){
return findParentNode(value, treeNode.getLeftTreeNode());
}else {
return null;
}
}
9.找树中的最小值并删除
java
public int min(TreeNode treeNode) {
TreeNode index = treeNode;
while(index.getLeftTreeNode()!=null) {
index = index.getLeftTreeNode();
}
delete(index.getValue(), root);
return index.getValue();
}
10.删除
- 删除叶子节点:
1.找到要删除的节点 target
2.找要删除节点的父亲节点 parent(考虑有没有父亲节点)
3.没有父亲节点(没有父亲节点又没有子节点,这棵树只有一个节点) 即 root=null
4.如果有父亲节点 确定target是parent的左孩子还是右孩子
如果是父亲节点的左孩子 parent.left=null
如果是父亲节点的右孩子 parent.right=null
2.删除只有一颗子树的节点
1.找到要删除的节点 target
2.找要删除节点的父亲节点 parent(考虑有没有父亲节点)
3.没有父亲节点 确定target是否有左右孩子
有左孩子 root=target.left
有右孩子 root=target.right
4.有父亲节点 确定target是parent的左孩子还是右孩子
左孩子 判断target是否有左右孩子
有左孩子 parent.left=target.left
有右孩子 parent.left=target.right
右孩子 判断target是否有左右孩子
有左孩子 parent.right= target.left
有右孩子 parent.right=target.right
3.删除有两棵子树的节点
1.找到要删除的节点 target
2.找target左子树的最大值或右子树的最小值
3.替换目标节点的值
4.删掉target左子树的最大值或右子树的最小值
java
public void delete(int value,TreeNode treeNode) {
if(treeNode==null) {
System.out.println("空树");
return;
}
//找目标节点
TreeNode target = find(value);
if(target==null) {
System.out.println("没有这个节点");
return;
}
//找目标节点的父节点
TreeNode parent = findParentNode(value, treeNode);
//删除节点
if(target.getLeftTreeNode()==null && target.getRightTreeNode()==null) {
//删除的是叶子节点
//没有父节点
if(parent==null) {
root=null;
}
//有父节点
if(parent!=null) {
//确定目标节点是父节点的左孩子还是右孩子
if(parent.getLeftTreeNode()!=null && parent.getLeftTreeNode().getValue()==value) {
//目标节点是父节点的左孩子
parent.setLeftTreeNode(null);
}else {
//目标节点是父节点的右孩子
parent.setRightTreeNode(null);
}
}
}else if(target.getLeftTreeNode()!=null && target.getRightTreeNode()!=null) {
//删除有两棵子树的节点
//找到目标节点右子树的最小值
int min = min(target.getRightTreeNode());
target.setValue(min);
}else {
//删除有一棵子树的节点
//没有父节点
if(parent==null) {
//确定目标节点有左孩子还是右孩子
if(target.getLeftTreeNode()!=null) {
//目标节点有左孩子
root=target.getLeftTreeNode();
}else {
//目标节点有右孩子
root=target.getRightTreeNode();
}
}
//有父节点
if(parent!=null) {
//确定目标节点是父节点的左孩子还是右孩子
if(parent.getLeftTreeNode()!=null && parent.getLeftTreeNode().getValue()==value) {
//目标节点是父节点的左孩子
//目标节点有左孩子还是右孩子?
if(target.getLeftTreeNode()!=null) {
//目标节点有左孩子
parent.setLeftTreeNode(target.getLeftTreeNode());
}else {
//目标节点有右孩子
parent.setLeftTreeNode(target.getRightTreeNode());
}
}else {
//目标节点是父节点的右孩子
//目标节点有左孩子还是右孩子?
if(target.getLeftTreeNode()!=null) {
//目标节点有左孩子
parent.setRightTreeNode(target.getLeftTreeNode());
}else {
//目标节点有右孩子
parent.setRightTreeNode(target.getRightTreeNode());
}
}
}
}
}