Java数据结构与算法实例讲解
发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,这篇文章主要讲解了"Java数据结构与算法实例讲解",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java数据结构与算法实例讲解"吧!为什么需要树这种结
千家信息网最后更新 2025年01月20日Java数据结构与算法实例讲解
这篇文章主要讲解了"Java数据结构与算法实例讲解",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java数据结构与算法实例讲解"吧!
为什么需要树这种结构
1.数组存储方式分析:
优点:通过下标方式访问元素,速度快。对于有序数组,还可以使用二分查找提高检索速度。
缺点:如果检索某个具体的值,或者插入值(按一定的顺序)会整体移动,效率较低。
2.链式存储方式分析:
优点:在一定程度上对数组存储方式优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可,删除效率很高)。
缺点:在进行检索时,效率仍然很低,需要从头结点开始遍历。
3.树存储方式分析:能提高数据存储,读取的效率,比如利用二叉排序树(Binary sort tree),即可以保证数据的检索速度,同时也可以保证数据的插入、删除、修改的速度。假设一组[7,3,10,1,5,9,12]以树的方式存储,分析如下图:
二叉树的前序遍历、中序遍历、后序遍历
前序遍历:输出父节点、输出左边节点、输出右边节点;
中序遍历:输出左边节点、输出父节点、输出右边节点;
后序遍历:输出左边节点、输出右边节点、输出父节点;
需求案例
完成一个如下二叉树节点存储、前序遍历搜索、中序遍历搜索、后序遍历搜索和删除节点功能。
对于删除节点要求如下:
鸿蒙官方战略合作共建--HarmonyOS技术社区
如果删除的节点是叶子节点,则删除该节点。
如果删除的节点是非叶子节点,则删除该树。
测试,删除5号叶子节点和3号子树。
代码案例
package com.xie.tree; public class BinaryTreeDemo { public static void main(String[] args) { BinaryTree binaryTree = new BinaryTree(); HeroNode root = new HeroNode(1, "宋江"); HeroNode node2 = new HeroNode(2, "吴用"); HeroNode node3 = new HeroNode(3, "卢俊义"); HeroNode node4 = new HeroNode(4, "林冲"); HeroNode node5 = new HeroNode(5, "关胜"); //先手动创建该二叉树,后面用递归方式 root.setLeft(node2); root.setRight(node3); node3.setRight(node4); node3.setLeft(node5); binaryTree.setRoot(root); //前序遍历 System.out.println("前序遍历"); binaryTree.preOrder(); //中序遍历 System.out.println("中序遍历"); binaryTree.infixOrder(); //后续遍历 System.out.println("后续遍历"); binaryTree.postOrder(); //前序遍历查找 System.out.println("前序遍历查找~~"); HeroNode resultNode = binaryTree.preOrderSearch(5); if (resultNode != null) { System.out.printf("找到了,信息为no=%d,name=%s\n", resultNode.getNo(), resultNode.getName()); System.out.println("遍历次数:" + HeroNode.preCount); } else { System.out.println("没有找到"); } //中序遍历查找 System.out.println("中序遍历查找~~"); HeroNode resultNode1 = binaryTree.infixOrderSearch(5); if (resultNode1 != null) { System.out.printf("找到了,信息为no=%d,name=%s\n", resultNode1.getNo(), resultNode1.getName()); System.out.println("遍历次数:" + HeroNode.infoxCount); } else { System.out.println("没有找到"); } //后序遍历查找 System.out.println("后序遍历查找~~"); HeroNode resultNode2 = binaryTree.postOrderSearch(5); if (resultNode2 != null) { System.out.printf("找到了,信息为no=%d,name=%s\n", resultNode2.getNo(), resultNode2.getName()); System.out.println("遍历次数:" + HeroNode.postCount); } else { System.out.println("没有找到"); } System.out.println("删除3号节点"); binaryTree.delNo(3); System.out.println("删除后的节点"); binaryTree.preOrder(); /** * 前序遍历 * HeroNode{no=1, name=宋江} * HeroNode{no=2, name=吴用} * HeroNode{no=3, name=卢俊义} * HeroNode{no=5, name=关胜} * HeroNode{no=4, name=林冲} * 中序遍历 * HeroNode{no=2, name=吴用} * HeroNode{no=1, name=宋江} * HeroNode{no=5, name=关胜} * HeroNode{no=3, name=卢俊义} * HeroNode{no=4, name=林冲} * 后续遍历 * HeroNode{no=2, name=吴用} * HeroNode{no=5, name=关胜} * HeroNode{no=4, name=林冲} * HeroNode{no=3, name=卢俊义} * HeroNode{no=1, name=宋江} * 前序遍历查找~~ * 找到了,信息为no=5,name=关胜 * 遍历次数:4 * 中序遍历查找~~ * 找到了,信息为no=5,name=关胜 * 遍历次数:3 * 后序遍历查找~~ * 找到了,信息为no=5,name=关胜 * 遍历次数:2 * 删除3号节点 * 删除后的节点 * HeroNode{no=1, name=宋江} * HeroNode{no=2, name=吴用} */ } } class BinaryTree { private HeroNode root; public void setRoot(HeroNode root) { this.root = root; } //前序遍历 public void preOrder() { if (this.root != null) { this.root.preOrder(); } } //中序遍历 public void infixOrder() { if (this.root != null) { this.root.infixOrder(); } } //删除节点 public void delNo(int no) { if (this.root != null) { if (this.root.getNo() == no) { this.root = null; } else { this.root.delNo(no); } } return; } //后序遍历 public void postOrder() { if (this.root != null) { this.root.postOrder(); } } //前序遍历查找 public HeroNode preOrderSearch(int no) { if (root != null) { return root.preOrderSearch(no); } else { return null; } } //中序遍历查找 public HeroNode infixOrderSearch(int no) { if (root != null) { return root.infixOrderSearch(no); } else { return null; } } //后序遍历查找 public HeroNode postOrderSearch(int no) { if (root != null) { return root.postOrderSearch(no); } else { return null; } } } class HeroNode { static int preCount = 0; static int infoxCount = 0; static int postCount = 0; private int no; private String name; private HeroNode left; private HeroNode right; public HeroNode(int no, String name) { this.no = no; this.name = name; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } public HeroNode getLeft() { return left; } public void setLeft(HeroNode left) { this.left = left; } public HeroNode getRight() { return right; } public void setRight(HeroNode right) { this.right = right; } @Override public String toString() { return "HeroNode{" + "no=" + no + ", name=" + name + '}'; } //前序遍历 public void preOrder() { System.out.println(this); //递归向左子树前序遍历 if (this.left != null) { this.left.preOrder(); } //递归向右子树前序遍历 if (this.right != null) { this.right.preOrder(); } } //中序遍历 public void infixOrder() { //递归向左子树中序遍历 if (this.left != null) { this.left.infixOrder(); } System.out.println(this); //递归向右子树中序遍历 if (this.right != null) { this.right.infixOrder(); } } //后序遍历 public void postOrder() { //递归向左子树后序遍历 if (this.left != null) { this.left.postOrder(); } //递归向右子树后序遍历 if (this.right != null) { this.right.postOrder(); } System.out.println(this); } //递归删除节点 //1.如果删除的节点是叶子节点,则删除该节点。 //2.如果删除的节点是非叶子节点,则删除该树。 public void delNo(int no) { /** * 1.因为我们的二叉树是单向的,所以我们是判断当前节点的子节点是否是需要删除的节点,而不能去判断当前节点是否是需要删除的节点。 * 2.如果当前节点的左子节点不为空,并且左子节点就是需要删除的节点,就将this.left = null;并且返回(结束递归)。 * 3.如果当前节点的右子节点不为空,并且右子节点就是需要删除的节点,将将this.right = null;并且返回(结束递归)。 * 4.如果第2步和第3步没有删除节点,那么就要向左子树进行递归删除。 * 5.如果第4步也没有删除节点,则应当向右子树进行递归删除。 */ if (this.left != null && this.left.no == no) { this.left = null; return; } if (this.right != null && this.right.no == no) { this.right = null; return; } if (this.left != null) { this.left.delNo(no); } if (this.right != null) { this.right.delNo(no); } } //前序遍历查找 public HeroNode preOrderSearch(int no) { HeroNode res = null; preCount++;//这里必须放在this.no == no 判断之前,才进行实际的比较 //若果找到,就返回 if (this.no == no) { return this; } //没有找到,向左子树递归进行前序查找 if (this.left != null) { res = this.left.preOrderSearch(no); } //如果res != null 就直接返回 if (res != null) { return res; } //如果左子树没有找打,向右子树进行前序查找 if (this.right != null) { res = this.right.preOrderSearch(no); } //如果找到就返回 if (res != null) { return res; } return res; } //中序遍历查找 public HeroNode infixOrderSearch(int no) { HeroNode res = null; if (this.left != null) { res = this.left.infixOrderSearch(no); } if (res != null) { return res; } infoxCount++;//这里必须放在this.no == no 判断之前,才进行实际的比较 if (this.no == no) { return this; } if (this.right != null) { res = this.right.infixOrderSearch(no); } if (res != null) { return res; } return res; } //后序遍历查找 public HeroNode postOrderSearch(int no) { HeroNode res = null; if (this.left != null) { res = this.left.postOrderSearch(no); } if (res != null) { return res; } if (this.right != null) { res = this.right.postOrderSearch(no); } if (res != null) { return res; } postCount++;//这里必须放在this.no == no 判断之前,才进行实际的比较 if (this.no == no) { return this; } return res; } }
感谢各位的阅读,以上就是"Java数据结构与算法实例讲解"的内容了,经过本文的学习后,相信大家对Java数据结构与算法实例讲解这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
节点
递归
子树
输出
数据
方式
存储
信息
次数
结构
叶子
宋江
实例
数据结构
算法
效率
速度
林冲
分析
检索
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库1061错误代码
怎样查网站服务器地址
鄂州服务器回收怎样收费
连云港支点网络技术
百度网盘服务器
康明斯与软件开发
亿赞普中国网络技术
江苏宿迁网络技术学院
数据库营销的商业价值
百度答题服务器繁忙请重试
数据库改密码
分布式云服务器
数据库前端设计
宽城县网络安全和信息化
怎么用本地数据库数据类型
工业网络技术现状
渭南软件开发商家
中孚信息软件开发怎么样
摄像数据库文件未就绪
数据库中的锁在哪
北京hp服务器阵列卡驱动服务器
服务器管理工资高
佛山市昇昊软件开发有限公司
软件开发算工程费吗
免费云电脑服务器ip
网络安全第二版胡道元编著
hp服务器心性的指示灯
网络安全产品单位
深圳律溶软件开发
互联网推广公司首选黔文科技