Java基础复习笔记07数据结构树的概述.docx

上传人:b****6 文档编号:5027433 上传时间:2022-12-12 格式:DOCX 页数:20 大小:28.37KB
下载 相关 举报
Java基础复习笔记07数据结构树的概述.docx_第1页
第1页 / 共20页
Java基础复习笔记07数据结构树的概述.docx_第2页
第2页 / 共20页
Java基础复习笔记07数据结构树的概述.docx_第3页
第3页 / 共20页
Java基础复习笔记07数据结构树的概述.docx_第4页
第4页 / 共20页
Java基础复习笔记07数据结构树的概述.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

Java基础复习笔记07数据结构树的概述.docx

《Java基础复习笔记07数据结构树的概述.docx》由会员分享,可在线阅读,更多相关《Java基础复习笔记07数据结构树的概述.docx(20页珍藏版)》请在冰豆网上搜索。

Java基础复习笔记07数据结构树的概述.docx

Java基础复习笔记07数据结构树的概述

Java基础复习笔记07数据结构-树的概述

刘岩

Email:

suhuanzheng7784877@

1.树的概念

如果线性表、栈、队列是线性结构(一维结构)的话,那么树就代表着一种非线性的、复杂的二维结构,何为线性结构、何为二维结构?

就是1对1的一条直线,每个元素都是这条线上的节点、节点之间只知道1VS1的、前后关系。

而二维结构就是一个面,1对N的一个面,这个面上的每一个元素都对应着多个此面上其他的元素。

树就是指N个有父子关系的节点的有限集合。

树仅仅只能有一个根节点。

除了根节点,其他没有子节点的节点叫做叶子节点。

树的遍历是最考究程序员算法的,因为后面的算法很多用到了一些概念,那先将树的有关概念解释一下。

节点的度:

节点拥有的子树的个数

树的度:

树中所有节点的度的最大值

节点的层次:

从根节点开始算起,根的层次为1,其余节点层次为父节点层次+1。

树的深度:

树中节点的最大层次值称为树的深度。

2.树的基本操作:

树的操作有以下:

为指定节点增加子节点、判断树是否为空、返回树的根节点、返回指定节点的父节点、返回指定节点的所有子节点集合、返回指定节点的第i个子节点、返回树的深度、返回指定节点的深度、返回指定节点的索引位置。

3.树的使用场景

树形结构使用场景非常之多,抛开编程语言不说,就看身边的例子。

大家windows的资源管理器、开发web系统的树形菜单、负载均衡的内核算法可以使用哈夫曼树来辅助实现、将要排序的数据用排序二叉树存储,查找的效率很快。

4.树的记父节点实现

书上管其叫做父节点表示法,这个名称我觉得很容易让人产生不解,所以笔者管它叫做记父节点实现更好一些。

它的算法的原理就是利用一个节点对象,该节点对象不仅记录了该节点的数据,还记录了此节点的父节点的位置。

那么我们访问这个节点的时候,实际上父节点也能间接的获取到了。

其实我们在做很多数据库设计的时候,遇到一个树形菜单基本上都是采用这种记父方式来实现的。

其实很多的看似二维的结构,数据库记录,都可以提取出相应的一种图形化的模型。

就像UML的类图关系就完全可以转化成关系型结构化数据库表模型,而数据库表结构也能提取出相应的领域模型一样。

主键

数据

父节点主键

0

根菜单

-1

1

子菜单1

0

2

子菜单2

0

3

子菜单11

1

上面的二维表结构可以描绘成以下结构

算法如下:

packagedateStructer.tree;

importjava.util.ArrayList;

importjava.util.List;

publicclassTreeParent{

/**

*节点结构

*/

publicclassNode{

//真正的数据域

privateEdate;

//记录父节点的索引位置

privateintparentIndex;

publicNode(){

}

publicNode(Edate,intparentIndex){

this.date=date;

this.parentIndex=parentIndex;

}

@Override

publicbooleanequals(Objectobj){

if(((Node)obj).date==this.date

&&((Node)obj).parentIndex==this.parentIndex)

returntrue;

returnfalse;

}

@Override

publicinthashCode(){

returnsuper.hashCode();

}

@Override

publicStringtoString(){

return(String)date;

}

}

//默认数组大小

privatefinalintDefSize=150;

//记录节点个数

privateintnodeSize;

//父节点对象

privateNode[]nodes;

publicTreeParent(){

nodes=newNode[DefSize];

}

publicTreeParent(Ee){

nodes=newNode[DefSize];

nodeSize++;

nodes[0]=newNode(e,-1);

}

/**

*为指定节点增加子节点

*

*@parame

*@paramparentNode

*@return

*/

publicbooleanaddNodeByParent(Ee,NodeparentNode){

for(inti=0;i

if(nodes[i]==null){

intparentNodeIndex=getNodeIndex(parentNode);

nodes[i]=newNode(e,parentNodeIndex);

nodeSize++;

returntrue;

}

}

returnfalse;

}

/**

*根据node获得索引

*

*@paramnode

*@return

*/

publicintgetNodeIndex(Nodenode){

for(inti=0;i

if(nodes[i].equals(node)){

returni;

}

}

return-1;

}

/**

*判断是否是空树

*

*@return

*/

publicbooleanisEmpty(){

returnnodeSize==0;

}

/**

*返回树的根节点

*

*@return

*/

publicNodegetRootNode(){

if(nodeSize==0){

returnnull;

}

returnnodes[0];

}

/**

*根据子节点返回父节点对象

*

*@paramchileNode

*@return

*/

publicNodegetParentNodeByChildNode(NodechileNode){

for(inti=0;i

if(chileNode==null){

returnnull;

}

if(i==chileNode.parentIndex){

returnnodes[i];

}

}

returnnull;

}

/**

*根据父节点返回子节点对象集合

*

*@paramchileNode

*@return

*/

publicNodegetParentNodeByChildNode(NodechileNode){

if(chileNode==null){

returnnull;

}

returnnodes[chileNode.parentIndex];

}

/**

*返回指定节点的第index个子节点,第1个代表第一个

*

*@paramparentNode

*@paramindex

*@return

*/

publicNodegetIndexChildByParentNode(NodeparentNode,intindex){

if(index==0){

thrownewRuntimeException("没有第0个子节点,从1开始");

}

intchildCount=0;

intparentIndex=getNodeIndex(parentNode);

for(inti=0;i

if(nodes[i].parentIndex==parentIndex){

++childCount;

if(childCount==index){

returnnodes[i];

}

}

}

returnnull;

}

/**

*返回节点的深度

*

*@return

*/

publicintreturnNodeDeep(Nodenode){

if(node==getRootNode()){

return1;

}else{

NodeparentNode=getParentNodeByChildNode(node);

if(parentNode!

=null){

returnreturnNodeDeep(parentNode)+1;

}

return0;

}

}

/**

*返回树的深度

*

*@return

*/

publicintreturnTreeDeep(){

intmax=0;

for(inti=0;i

intnodeDeep=returnNodeDeep(nodes[i]);

if(max

max=nodeDeep;

}

}

returnmax;

}

@Override

publicStringtoString(){

StringBufferstr=newStringBuffer("[");

for(inti=0;i

str.append("["+nodes[i].date+"],");

}

if(nodeSize>0){

returnstr.substring(0,str.lastIndexOf(","))+"]";

}

returnstr.append("]").toString();

}

}

测试代码

publicstaticvoidmain(String[]args){

TreeParenttree=newTreeParent("根菜单");

TreeParent.Noderoot=tree.getRootNode();

tree.addNodeByParent("子菜单1",root);

tree.addNodeByParent("子菜单2",root);

TreeParent.Nodenode1=tree.getIndexChildByParentNode(root,1);

tree.addNodeByParent("子菜单11",node1);

System.out.println("树的数据:

"+tree);

System.out.println("节点的深度:

"+tree.returnNodeDeep(node1));

System.out.println("节点的深度:

"+tree.returnNodeDeep(root));

TreeParent.Nodenode11=tree.getIndexChildByParentNode(node1,1);

System.out.println("节点的深度:

"+tree.returnNodeDeep(node11));

System.out.println("树的深度:

"+tree.returnTreeDeep());

}

测试效果如下

树的数据:

[[根菜单],[子菜单1],[子菜单2],[子菜单11]]

节点的深度:

2

节点的深度:

1

节点的深度:

3

树的深度:

3

记父节点是让树的节点记住自己节点的父节点索引位置,可以根据索引查找父节点,查找某个节点的父节点自然是手到擒来了,但是查找某个节点的子节点就略显笨拙,得遍历整个树的存储数组。

5.树的记子节点实现

与记父节点不同的是,记子节点实现是Node节点记录的是自己子节点的信息,之后利用第一个子节点记录第二个子节点信息、利用第二个子节点记录第三个字节点信息,以此类推。

也就是说子节点对象就是记录父节点的子节点信息的。

第n个节点记录了第n+1个子节点的信息。

代码如下

packagedateStructer.tree;

importjava.util.ArrayList;

importjava.util.List;

publicclassTreeChildren{

/**

*记录子节点对象

*

*@authorliuyan

*/

classSonNode{

Edata;

intindex;

SonNodesonNode;

publicSonNode(Edata,intindex,SonNodesonNode){

this.data=data;

this.index=index;

this.sonNode=sonNode;

}

@Override

publicStringtoString(){

return(String)data;

}

publicNodepaseNode(){

returnnewNode(data,index);

}

}

/**

*实际应用的Node对象

*

*@authorliuyan

*/

classNode{

Edata;

intindex;

SonNodefirstSonNode;

publicNode(Edata,intindex){

this.data=data;

this.index=index;

}

publicNode(Edata,intindex,SonNodesonNode){

this.data=data;

this.index=index;

this.firstSonNode=sonNode;

}

@Override

publicbooleanequals(Objectobj){

if(((Node)obj).data==this.data

&&((Node)obj).index==this.index)

returntrue;

returnfalse;

}

@Override

publicinthashCode(){

returnsuper.hashCode();

}

@Override

publicStringtoString(){

return(String)data;

}

}

//默认数组大小

privatefinalintDefSize=150;

//记录节点个数

privateintnodeSize;

//父节点对象

privateNode[]nodes;

publicTreeChildren(){

nodes=newNode[DefSize];

}

publicTreeChildren(Ee){

nodes=newNode[DefSize];

nodeSize++;

nodes[0]=newNode(e,0);

}

/**

*为指定节点增加子节点

*

*@parame

*@paramparentNode

*@return

*/

@SuppressWarnings("unchecked")

publicbooleanaddNodeByParent(Ee,NodeparentNode){

for(inti=0;i

if(nodes[i]==null){

SonNodesonNode=newSonNode(e,i,null);

SonNodelastSonNode=getLastSonNodeByParent(parentNode);

if(lastSonNode==null){

parentNode.firstSonNode=sonNode;

}else{

lastSonNode.sonNode=sonNode;

}

nodes[i]=sonNode.paseNode();

nodeSize++;

returntrue;

}

}

returnfalse;

}

/**

*由SonNode到普通Node的转化

*@paramsonNode

*@return

*/

publicNodepaseNode(SonNodesonNode){

for(inti=0;i

if(nodes[i]!

=null&&nodes[i].data==sonNode.data

&&nodes[i].index==sonNode.index){

returnnodes[i];

}

}

returnnull;

}

/**

*获得一个父节点的最后子节点对象

*

*@paramparentNode

*@return

*/

@SuppressWarnings("unchecked")

publicSonNodegetLastSonNodeByParent(NodeparentNode){

if(parentNode.firstSonNode==null){

returnnull;

}

SonNodesonNodeNow=parentNode.firstSonNode;

while(sonNodeNow.sonNode!

=null){

sonNodeNow=sonNodeNow.sonNode;

}

returnsonNodeNow;

}

/**

*根据node获得索引

*

*@paramnode

*@return

*/

publicintgetNodeIndex(Nodenode){

for(inti=0;i

if(nodes[i].equals(node)){

returni;

}

}

return-1;

}

/**

*判断是否是空树

*

*@return

*/

publicbooleanisEmpty(){

returnnodeSize==0;

}

/**

*返回树的根节点

*

*@return

*/

publicNodegetRootNode(){

if(nodeSize==0){

returnnull;

}

returnnodes[0];

}

/**

*根据子节点返回父节点对象

*

*@paramchileNode

*@return

*/

@SuppressWarnings("unchecked")

publicNodegetParentNodeByChildNode(NodechileNode){

for(inti=0;i

if(nodes[i]!

=null&&nodes[i].firstSonNode!

=null){

SonNodesonNode=nodes[i].firstSonNode;

while(sonNode!

=null){

if(sonNode.data==chileNode.data

&&sonNode.index==chileNode.index){

returnnodes[i];

}

sonNode=sonNode.sonNode;

}

}

}

returnnull;

}

/**

*根据父节点返回父子节点对象集合

*

*@paramchileNode

*@return

*/

@SuppressWarnings("unchecked")

publicList>getChildsNodeByParentNode(NodeparentNode){

if(parentNode==null){

returnnull;

}

SonNodesonNodeNow=parentNode.firstSonNode;

List>list=newArrayList>();

while(sonNodeNow.sonNode!

=null){

list.add(s

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1