node = node.getRchild(); //根节点<数据,向右走
}
}
return node;
}
//查找最大值:不断地寻找右子节点
public TreeNode getMaxData(TreeNode node){
if(node.getRchild() == null){
return node;
}else{
return getMaxData(node.getRchild());
}
}
//查找最小值:不断地寻找左子节点
public TreeNode getMinData(TreeNode node){
if(node.getLchild() == null){
return node;
}else{
return getMinData(node.getLchild());
}
}
//得到数据域为data的结点的直接父节点parentNode
public TreeNode getParentNode(TreeNode root, Integer data){
TreeNode parentNode = root;
if(parentNode.getData() == data){ //根节点的父节点返回为null
return null;
}
while(parentNode != null){
//查找当前节点的父节点的左右子节点,若是相等,则返回该父节点
if((parentNode.getLchild() != null && parentNode.getLchild().getData() == data) ||
(parentNode.getRchild() != null && parentNode.getRchild().getData() == data)){
return parentNode;
}else{
if(parentNode.getData() > data){ //向左查找父节点
parentNode = parentNode.getLchild();
}else{
parentNode = parentNode.getRchild(); //向右查找父节点
}
}
}
return null;
}
/**
-
得到结点node的直接前趋
-
a.该节点左子树不为空:其前驱节点为其左子树的最大元素
-
b.该节点左子树为空: 其前驱节点为其祖先节点(递归),且该祖先节点的右孩子也为其祖先节点
-
(就是一直往其parent找,出现左拐后的那个祖先节点)
*/
public TreeNode getPrecessor(TreeNode root,TreeNode node){
if(node == null){
return null;
}
//a.该节点左子树不为空:其前驱节点为其左子树的最大元素
if(node.getLchild() != null){
return getMaxData(node.getLchild());
}else{ //b.该节点左子树为空: 其前驱节点为其祖先节点(递归)
TreeNode parentNode = getParentNode(root, node.getData());
while(parentNode != null && node == parentNode.getLchild()){
node = parentNode;
parentNode = getParentNode(root, parentNode.getData());
}
return parentNode;
}
}
/**
-
得到结点node的直接后继(后继节点就是比要删除的节点的关键值要大的节点集合中的最小值)
-
a.该节点右子树不为空,其后继节点为其右子树的最小元素
-
b.该节点右子树为空,则其后继节点为其祖先节点(递归),且此祖先节点的左孩子也是该节点的祖先节点,
-
就是说一直往上找其祖先节点,直到出现右拐后的那个祖先节点:
*/
public TreeNode getSuccessor(TreeNode root,TreeNode node){
if(node == null){
return null;
}
//a.该节点右子树不为空,其后继节点为其右子树的最小元素
if(node.getRchild() != null){
return getMinData(node.getRchild());
}else{ //b.该节点右子树为空,则其后继节点为其最高祖先节点(递归)
TreeNode parentNode = getParentNode(root, node.getData());
while(parentNode != null && node == parentNode.getRchild()){
node = parentNode;
parentNode = getParentNode(root, parentNode.getData());
}
return parentNode;
}
}
/**
-
删除数据域为data的结点
-
按三种情况处理:
-
a.如果被删除结点z是叶子节点,则直接删除,不会破坏二叉查找树的性质
-
b.如果节点z只有一颗左子树或右子树,则让z的子树成为z父节点的子树,代替z的位置
-
c.若结点z有左、右两颗子树,则令z的直接后继(或直接前驱)替代z,
-
然后从二叉查找树中删去这个直接后继(或直接前驱),这样就转换为第一或第二种情况
-
@param node 二叉查找树的根节点
-
@param data 需要删除的结点的数据域
-
@return
*/
public boolean deleteNode(TreeNode node, Integer data){
if(node == null){ //树为空
throw new RuntimeException(“树为空!”);
}
TreeNode delNode= searchNode(node, data); //搜索需要删除的结点
TreeNode parent = null;
if(delNode == null){ //如果树中不存在要删除的关键字
throw new RuntimeException(“树中不存在要删除的关键字!”);
}else{
parent = getParentNode(node,data); //得到删除节点的直接父节点
//a.如果被删除结点z是叶子节点,则直接删除,不会破坏二叉查找树的性质
if(delNode.getLchild()==null && delNode.getRchild()==null){
if(delNode==parent.getLchild()){ //被删除节点为其父节点的左孩子
parent.setLchild(null);
}else{ //被删除节点为其父节点的右孩子
parent.setRchild(null);
}
return true;
}
//b1.如果节点z只有一颗左子树,则让z的子树成为z父节点的子树,代替z的位置
if(delNode.getLchild()!=null && delNode.getRchild()==null){
if(delNode==parent.getLchild()){ //被删除节点为其父节点的左孩子
parent.setLchild(delNode.getLchild());
}else{ //被删除节点为其父节点的右孩子
parent.setRchild(delNode.getLchild());
}
delNode.setLchild(null); //设置被删除结点的左孩子为null
return true;
}
//b2.如果节点z只有一颗右子树,则让z的子树成为z父节点的子树,代替z的位置
if(delNode.getLchild()==null && delNode.getRchild()!=null){
if(delNode==parent.getLchild()){ //被删除节点为其父节点的左孩子
parent.setLchild(delNode.getRchild());
}else{ //被删除节点为其父节点的右孩子
parent.setRchild(delNode.getRchild());
}
delNode.setRchild(null); //设置被删除结点的右孩子为null
return true;
}
//c.若结点z有左、右两颗子树,则删除该结点的后继结点,并用该后继结点取代该结点
if(delNode.getLchild()!=null && delNode.getRchild()!=null){
TreeNode successorNode = getSuccessor(node,delNode); //得到被删除结点的后继节点
deleteNode(node,successorNode.getData()); //删除该结点的后继结点
delNode.setData(successorNode.getData()); //用该后继结点取代该结点
return true;
}
}
return false;
}
public static void main(String args[]){
Scanner input = new Scanner(System.in);
Integer[] array = {8,3,10,1,6,14,4,7,13};
BinarySearchTree bst = new BinarySearchTree();
TreeNode root = bst.buildBST(array);
System.out.print(“层次遍历:”);
bst.levelOrder(root);
System.out.print(“\n”+“中序遍历:”);
bst.inOrder(root);
System.out.println();
System.out.print(“得到最大值:”);
System.out.println(bst.getMaxData(root).getData());
System.out.print(“得到最小值:”);
System.out.println(bst.getMinData(root).getData());
System.out.print(“向二叉查找树中插入一个节点,请输入需插入节点的数据域:”);
int data = input.nextInt();
System.out.print(“插入节点”+ data +“后,中序遍历的结果:”);
root = bst.insertNode(root, data);
bst.inOrder(root);
System.out.println(“\n”+“在二叉查找树中查找元素,”+“请输入需要查找的结点值:”);
data = input.nextInt();
if(bst.searchNode(root, data) == null){
System.out.println(“false”);
}else{
System.out.println(“true”);
}
System.out.println(“查找节点的直接父节点,”+“请输入需要查找的结点值:”);
data = input.nextInt();
System.out.print(“节点”+ data +“的父节点是:”);
if(bst.getParentNode(root, data) == null){
System.out.println(“null”);
}else{
System.out.println(bst.getParentNode(root, data).getData());
}
System.out.println(“删除结点,”+“请输入需要删除的结点值:”);
data = input.nextInt();
if(bst.deleteNode(root, data)){
System.out.print(“删除结点后的层次遍历:”);
bst.levelOrder(root);
System.out.print(“\n”+“删除结点后的中序遍历:”);
bst.inOrder(root);
}
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
写在最后
还有一份JAVA核心知识点整理(PDF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />
写在最后
还有一份JAVA核心知识点整理(PDF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…
[外链图片转存中…(img-zZX4UafT-1712025262220)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!