数据结构java语言描述朱战立_数据结构——树(Java语言描述)

42b380559cbc96ff59c1d3206ea1f708.png

树根:rootNode. 树只有一个树根。

节点:Node. 树上的所有节点。

子节点数组:Node[]. 数组代表每个节点的所有子节点

父节点:parentNode. 每个节点只有一个父节点。

2. Node为Tree中的内部类

parent :指向父节点的引用

childern: 孩子数组,存储该节点的所有子节点。

T 为泛型参数,代表节点应该存储什么类型的数据,是该节点的数据域。

size: 该节点所有的孩子数目。(孩子数组中所有元素的数目)

3.Tree类(Tree就是对树进行增删改查的实现类,该类内部维护了一个树根节点。)

treeRoot:Tree进行维护的一个树根节点。

cur:代表当前节点的引用,用于各种方法中,减少空间复杂度。

DEFAULT_SIZE:孩子节点数组的默认大小,数值为10.

findNodes():该方法返回当前节点的孩子节点数组。

find():该方法实现返回树中节点的引用功能,用于遍历树节点并且提供当前操作节点的功能。

add():该方法实现对节点的添加,内部调用了find()与addNode()方法实现父类节点的查找与节点数组的动态扩容。

3.实现思路:

代码1:建立一个Tree类。该类内部维护一个顺序树,对外提供基于树的增删改查的方法.该代码是整个树结构的组成单元。

@SuppressWarnings(value = "all")public class Tree{//Tree构造器,构造一个TreeRoot

publicTree() {

treeRoot= newNode();

}//基于数组的树//孩子数组默认初始大小

static int DEFAULT_SIZE = 10;//树根,Tree对象负责维护该对象。

privateNode treeRoot;//指向当前叶子的指针

privateNode cur;//节点内部类,树结构的基本组成单位。

static class Node{//孩子数组中元素的个数

private int size = 0;//父节点指针

private Nodeparaent;private Node[] children = newNode[DEFAULT_SIZE];//叶子数据域

privateT t;//叶子名称

privateString name;//Node对外提供两个构造方法.一个无参构造用于构造树根元素,另外一个负责构造叶子节点元素。

publicNode() {this.name = "树根";

}publicNode(T t, String name) {this.t =t;this.name =name;

}

}

}

代码2:add方法的实现

//方法需要传入一个节点指针引用

public void add(Nodenode){//调用find()方法找到当前操作节点,然后通过addNode()方法添加到该节点的孩子数组中

Node parent =find();

addNode(parent, node);

}

代码3:find()方法的实现:方法实现树的查询操作。

(代码有点长,我写的时候也有点晕了,不过想象成你在操作文件夹理解起来也许就会轻松很多~)

public Nodefind(){//使当前节点成为树根节点

Node cur =treeRoot;

Scanner scanner= newScanner(System.in);//标识用户操作的字符串

String flag = null;//标识节点在数组中的下标变量

int index = 0;//用于接收当前节点的孩子数组

Node[] nodes = null;//需要在循环条件下对节点进行挑选操作

while(true){

System.out.println("当前父节点:"+cur.name);

System.out.println("当前节点添加或者是否继续遍历子节点?");//

//(ps:按1遍历当前节点的孩子数组,按2在当前节点插入叶子节点。就相当在当前文件夹添加文件,还是进入子文件夹中)

flag =scanner.nextLine();//如果选择1,则表示遍历当前节点的孩子数组。

if(flag.equals("1")){//通过finjNodes()方法得到当前节点的孩子节点数组

nodes =findNodes(cur);//如果数组中的元素个数为0,则结束本次操作。

if(cur.size==0){

System.out.println("无子节点,本次插入操作结束!");return null;

}//如果不为零则输出所有不为null的孩子节点

for (int i = 0; i < nodes.length; i++) {if(nodes[i]!=null)

System.out.print(nodes[i].name+"("+i+")"+" ");

}//选择一个节点进行操作

System.out.println("请选中一个节点(ps:选择方式根据括号下标)");//操作使用while循环,防止用户输入字符不是数字而跳出try语句块。

while(true){try{

index=Integer.valueOf(scanner.nextLine());

cur=nodes[index];if(cur==null){

System.out.println("节点不存在,请重新输入");continue;

}break;

}catch(Exception e) {

System.out.println("输入下标格式不正确,请重新输入!");

}

}

}//不为1,则返回当前节点。

else{/**try {

} finally {

//System.out.println("关闭流");

//scanner.close();这里关闭流了,然后下次调用该方法反而会引发异常??

}*/System.out.println();returncur;

}

}

}

代码4:addNode()方法:

//该方法传入一个父节点与一个子节点指针

public void addNode(Node parent, Nodenode) {//如果父节点不为null

if(parent!=null){//得到父节点所有孩子的数量

int size =parent.size;//在增加元素之前调用enSureSize()方法,进行是否需要扩容检查.

enSureSize(size+1, parent);//父节点增加一个元素

parent.children[size] =node;

parent.size++;

}

}

代码5: enSureSize()方法。检查是否需要调用gorw()方法实现动态扩容

public void enSureSize(intminCapcity, Node parent) {//minCapcity为父节点当前所有孩子的数量,从默认大小和孩子数量之间选择一个较大数

minCapcity =Math.max(DEFAULT_SIZE, minCapcity);//如果孩子数量超过了当前数组的长度,则调用grow()方法

if (minCapcity - parent.children.length > 0)

grow(minCapcity, parent);

}

代码6:grow()方法.。实现0.5倍的数组容量增长,或者整个数组的拷贝。

public void grow(int minCapcity, Nodeparent) {//限制数组的最大长度

if (minCapcity > Integer.MAX_VALUE - 8) {

System.out.print("数组长度超过最大长度限制");return;

}

Node[] arrys=parent.children;int oldLength =arrys.length, newLength;

newLength= oldLength + (int) (0.5 * oldLength);//0.5倍扩容//如果数量大于新的数组长度,则让孩子数量为新的数组长度

if (minCapcity >newLength)

newLength=minCapcity;//Arrays工具类提供的一个native方法,实现数组的高效拷贝。

parent.children =Arrays.copyOf(arrys, newLength);

}

代码7:主函数用for循环实现一个节点数为10的树

public static voidmain(String[] args) {//实例化一个类型为String的Tree

Tree tree = new Tree();for (int i = 0; i < 10; i++) {//生成十个数据域为(0-10)随机数,名称为"Node"+i的叶子

tree.add(new Node(""+(int)(Math.random()*10), "Node"+i));

}

}

5.说明:

因为时间和个人能力有限,这次对于树的操作算法繁琐且有缺陷,因为每次查询就不能再返回父节点的位置,有兴趣的童鞋可以修改下代码~~~~~

6.总结:

此篇文章是以自己的角度来想象树应该是有怎么样的一个结构,通过怎么样的方法可以对它进行一系列的操作.其实通过文件系统我们可以更加理解树的构造和基本操作,例如windows下磁盘驱动器就好比如树的根节点,其子文件就相当于树的一片片叶子。在驱动器的基础上我们可以建立许多的文件夹,文件夹又可以放入许多的文件夹…虽然只提供了查询和增加节点的操作,但是相信伙伴们能在find()方法的基础上对节点实现删除和更新操作.(后续继续二叉树和平衡二叉树的总结)

————————————————

版权声明:本文为CSDN博主「Mrjianghaokun」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Mrjianghaokun/article/details/99708541

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/351595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7.4进入单用户模式

centos7.4进入单用户模式 1 - 在启动grub菜单&#xff0c;选择编辑选项启动2 - 按键盘e键&#xff0c;来进入编辑界面 3 - 找到Linux 16的那一行&#xff0c;将ro改为rw init/sysroot/bin/sh 4 - 现在按下 Controlx &#xff0c;使用单用户模式启动 5 - 现在&#xff0c;可以使…

判断某程序是64位还是32位

1. 用代码判断本身if (IntPtr.Size 4) {// 32-bit}else if (IntPtr.Size 8){// 64-bit}2. 用代码判断正在运行的其他进程http://stackoverflow.com/questions/1953377/how-to-know-a-process-is-32-bit-or-64-bit-programmatically3. 不用代码判断任意exe&#xff0c;看第二个…

MySQL 中 NULLIF 、IFNULL、IF 的用法和区别

在 MySQL 中&#xff0c;NULLIF、IFNULL 和 IF 是用于处理 NULL 值的三种不同的函数。 1. NULLIF 函数 NULLIF 函数用于比较两个表达式&#xff0c;如果它们的值相等&#xff0c;则返回 NULL&#xff0c;否则返回第一个表达式的值。语法如下&#xff1a; NULLIF(expr1, expr2…

32和64位jvm_我应该使用32位还是64位JVM?

32和64位jvm这是我在企业软件开发生涯中多次遇到的问题。 我不得不每隔一段时间就提供有关配置特定新环境的建议。 而且&#xff0c;很多时候&#xff0c;手头的问题与“我应该使用32位或64位JVM”有关。 老实说&#xff0c;一开始我只是掷硬币。 而不是给出合理的答案。 &…

spring java code配置_Spring-09-使用Java的方式配置Spring

9. 使用Java的方式配置Spring我们现在要完全不使用Spring的xml配置&#xff0c;全权使用Java来配置Spring&#xff01;JavaConfig是Spring的一个子项目&#xff0c;在Spring4之后&#xff0c;他成为了一个核心功能。实体类&#xff1a;public class User {private String name;…

pythone函数基础(11)读,写,修改EXCEL

#读EXCEL需要导入xlrd模块---在python控制台pip install xlrd模块import xlrdbook xlrd.open_workbook(stu3.xls)sheet book.sheet_by_index(0)# sheet book.sheet_by_name(sheet1)# print(sheet.cell(0,0).value)#获取指定单元格的内容# print(sheet.cell(1,0).value)# pri…

强大的vim配置文件,让编程更随意

花了很长时间整理的&#xff0c;感觉用起来很方便&#xff0c;共享一下。 我的vim配置主要有以下优点&#xff1a; 1.按F5可以直接编译并执行C、C、java代码以及执行shell脚本&#xff0c;按“F8”可进行C、C代码的调试 2.自动插入文件头 &#xff0c;新建C、C源文件时自动插…

java工程转maven工程_将java工程转换为Maven工程

1、创建一个Java工程&#xff0c;如下图所示&#xff1a;2、选中此工程 -> 右键 -> Configure -> Convert to Maven project。出现如下的截图&#xff1a;3、点击之后会弹出对话框&#xff0c;如下图所示&#xff1a;4、直接点击完成即可&#xff0c;此时会在java工程…

2019/4/17 Linux学习

一、Linux的文件系统 其中/prov、/srv、/sys 文件为文件系统&#xff0c;技术不过硬不要去修改&#xff1b;二、关于Xshell、Xft1、服务器的端口可有65535个可设置&#xff0c;开的越多安全性越差&#xff1b;2、远程登录主机时&#xff0c;会有一个sshd程序&#xff0c;22端口…

使用“另类” Cloud Foundry Gradle插件无需停机

我一直在尝试我的手在写一个gradle这个插件的应用程序部署到Cloud Foundry上 &#xff0c;并写下这个插件在我以前的帖子 。 我现在通过使用两种方法支持将无停机时间部署到Cloud Foundry中来增强此插件&#xff1a; 自动驾驶风格部署和更常用的蓝绿色风格部署 。 要完全了解该…

UNIX网络编程 卷2 源代码使用

1. 下载源码&#xff0c;W. Richard Stevens的主页&#xff1a;http://www.kohala.com/start/wget http://www.kohala.com/start/unpv22e/unpv22e.tar.gz -P /usr/local/src 2. 解压tar xvf /usr/local/src/unpv22e.tar.gz -C /root/bin 3. 编译库文件cd /root/bin/unpv22e/ .…

语言工程中有趣的事情

如果您阅读此博客&#xff0c;您将知道我坚信语言的力量。 因此&#xff0c;我当然有很大的偏见&#xff0c;但是我感觉语言工程社区正在增长&#xff0c;并且越来越有趣的东西正在涌现。 为此&#xff0c;我认为通过查看社区中正在发生的事情并列出一些我发现有趣的事情来结束…

操作 实例 / dom

响应式&#xff1a;数据改变时会触发其他联动。例如&#xff1a;模板中的数据绑定&#xff1b;计算属性的重新计算&#xff1b;———————————————————————————————————————————————————— vm.$parent $parent 属性可以用来从…

sql注入程序_Java应用程序中SQL注入

sql注入程序在本文中&#xff0c;我们将讨论什么是SQL注入攻击。 以及它如何影响任何Web应用程序使用后端数据库。 在这里&#xff0c;我专注于Java Web应用程序。 开放Web应用程序安全性项目&#xff08;OWAP&#xff09;列出了SQL注入是Web应用程序的主要漏洞攻击。 黑客将We…

C++设计模式-Prototype原型模式

作用&#xff1a; 用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象。 Prototype模式提供了一个通过已存在对象进行新对象创建的接口&#xff08;Clone&#xff09;&#xff0c; Clone()实现和具体的语言相关&#xff0c;在C中通过拷贝构造函数实现。…

[SHOI2008]cactus仙人掌图

Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路&#xff08;simple cycle&#xff09;里&#xff0c;我们就称这张图为仙人掌图&#xff08;cactus&#xff09;。所谓简单回路就是指在图上不重复经过任何一个顶点的回路。 举例来说&#xff0c;上面的第一…

java 导入导出txt文件_Java读取和写入txt文件

1 问题描述对于java的读取和写入txt一直心存疑惑&#xff0c;随着知识的积累&#xff0c;又重新进行学习&#xff0c;对java的文件读写理解更加深刻&#xff0c;在这里将自己的小小经验总结分享给大家。下面是大家了解java流的一个基本框架。2 问题分析在java中&#xff0c;jav…

[国家集训队] tree Ⅱ

bzoj2631&#xff08;权限题。。。&#xff09;:链接 落咕:链接 考察的是LCT维护链上信息。 但是这个题不一样的是又有加法又有乘法。。。&#xff08;有木有想到落咕的模板——线段树2qwq&#xff09; 因为乘法的运算优先度比加法高&#xff0c;所以我们要先做乘法再做加法&am…

C++拷贝构造函数(深拷贝,浅拷贝)

对于普通类型的对象来说&#xff0c;它们之间的复制是很简单的&#xff0c;例如&#xff1a; int a88; int ba; 而类对象与普通对象不同&#xff0c;类对象内部结构一般较为复杂&#xff0c;存在各种成员变量。下面看一个类对象拷贝的简单例子。 #include <iostream>u…

java用for循环修改密码_Java for循环的几种用法分析

J2SE 1.5提供了另一种形式的for循环。借助这种形式的for循环&#xff0c;可以用更简单地方式来遍历数组和Collection等类型的对象。本文介绍使用这种循环的具体方式&#xff0c;说明如何自行定义能被这样遍历的类&#xff0c;并解释和这一机制的一些常见问题。在Java程序中&…