1、树定义和基本术语

节点

package com.young.tree;/*** <p>* Title:树节点:二叉链表结构* </p>** @Author: yangyongbing* @Date: 2023-04-18 13:25* @version: v1.0*/
public class Node<T> {public Node<T> lChild;private T data;public Node<T> rChild;public Node() {lChild=null;data=null;rChild=null;}public Node(T data) {this.data = data;this.lChild=null;this.rChild=null;}public Node<T> getlChild() {return lChild;}public void setlChild(Node<T> lChild) {this.lChild = lChild;}public T getData() {return data;}public void setData(T data) {this.data = data;}public Node<T> getrChild() {return rChild;}public void setrChild(Node<T> rChild) {this.rChild = rChild;}
}

二叉树

package com.young.tree;/*** <p>* Title: 二叉树* </p>** @Author: yangyongbing* @Date: 2023-04-18* @version: v1.0*/
public class BinaryTree<T> {private final int maxNodes = 100;// 根节点public Node<T> root;// 创建一棵空二叉树public BinaryTree() {this.root = new Node<>();}// 创建一棵以数据元素x为根节点的二叉树public BinaryTree(T x) {this.root = new Node<>(x);}/*在当前二叉树的parent结点中插入一个新的左子结点,若已存在左子树,则将该左子树变成新左子结点的左孩子树*/public boolean addLeft(T x, Node<T> parent) {if (parent == null) {return false;}// 创建一个空节点Node<T> p = new Node<>(x);// 如果父节点的左子树为空,则直接将数据素x赋给父节点的左孩子节点if (parent.lChild != null) {// 将父节点的左子树赋给这个新节点左子节点p.lChild = parent.lChild;}// 将新节点赋给父节点的左孩子节点parent.lChild = p;return true;}/*在当前二叉树的parent结点中插入一个新的右子节点,若已存在右子树,则将该右子树变成新右子节点的右孩子树*/public boolean addRight(T x, Node<T> parent) {if (parent == null) {return false;}// 创建一个空节点Node<T> p = new Node<>(x);if (parent.rChild != null) {p.rChild = parent.rChild;}parent.rChild = p;return true;}// 删除当前二叉树的parent节点中的左子树public boolean deleteLeft(Node<T> parent) {if (parent == null) {return false;} else {parent.lChild = null;return true;}}// 删除当前二叉树的parent节点中的右子树public boolean deleteRight(Node<T> parent) {if (parent == null) {return false;} else {parent.rChild = null;return true;}}// 先序遍历public void preorder(Node<T> node) {if (node != null) {// 访问根节点visit(node.getData());// 先序遍历左子树preorder(node.getlChild());// 先序遍历右子树preorder(node.getrChild());}}// 中序遍历public void inorder(Node<T> node) {if (node != null) {// 中序遍历左子树inorder(node.lChild);// 访问根节点visit(node.getData());// 中序遍历右子树inorder(node.rChild);}}// 后序遍历public void postorder(Node<T> node) {if (node != null) {// 后续遍历左子树postorder(node.lChild);// 后续遍历右子树postorder(node.rChild);// 访问根节点visit(node.getData());}}// 按层次遍历public void levelOrder() {// 节点数组,用于存放节点Node<T>[] queue = new Node[this.maxNodes];if (this.root == null) {return;}// 定义队首和队尾指针int front, rear;// 队列为空,对首指针不指向任何一个数组元素front = -1;// 队列为空,对尾指针指向数组第一个位置rear = 0;// 根节点入队queue[rear] = this.root;while (front != rear) {// 访问对首节点的数据域front++;visit(queue[front].getData());// 左节点入队if (queue[front].lChild != null) {rear++;queue[rear] = queue[front].lChild;}// 右节点入队if (queue[front].rChild != null) {rear++;queue[rear] = queue[front].rChild;}}}private void visit(T x) {System.out.println(x);}// 在当前二叉树中查找数据xpublic boolean search(Node<T> node,T x) {if (node != null) {// 访问根节点T t = node.getData();if(x==t){return true;}// 先序遍历左子树search(node.getlChild(),x);// 先序遍历右子树search(node.getrChild(),x);}return false;}// 按某种方式遍历二叉树中的所有节点//按指定方式遍历二叉树//i=0表示先序遍历,=1表示中序遍历,=2表示后序遍历,=3表示层次遍历public void traversal(int i){switch(i){case 0: preorder(this.root);break;case 1: inorder(this.root);break;case 2: postorder(this.root);break;default: levelOrder();}}// 求当前二叉树的高度public int getHeight(Node<T> parent) {int lh,rh,max;if(parent!=null){lh=getHeight(parent.lChild);rh=getHeight(parent.rChild);max= Math.max(lh, rh);return max+1;}return 0;}
}

1.1、树定义

树(Tree)是若干个结点组成的有限集合,其中必须有一个结点是根结点,其余结点划分为若干个互不相交的集合,每一个集合还是一棵树,但被称为根的子树。注意,当树的结点个数为0时,我们称这棵树为空树,记为Φ。
特点:

  • 树的根结点没有前驱结点,除根结点之外的所有结点有且只有一个前驱结点。
  • 树中所有结点可以有零个或多个后继结点。

1.2、术语

  • 结点:表示树中的元素,包括数据项及若干指向其子树的分支。
  • 结点的度:结点所拥有的子树的个数称为该结点的度。
  • 叶子结点:度为0的结点称为叶子结点,或者称为终端结点。
  • 分支结点:度不为0的结点称为分支结点,或者称为非终端结点。一棵树的结点除叶子结点外,其余的都是分支结点。
  • 孩子、双亲、兄弟:若在树中一个结点A的子树的根结点是B,则称B为A的孩子(也称子结点),称A为B的双亲(也称父节点)。具有同一个双亲的子结点互称为兄弟。
  • 路径、路径长度:如果一棵树的一串结点n1,n2,…,nk有如下关系,即结点ni是ni+1的父结点(1≤i<k),就把n1,n2,…,nk称为一条由n1至nk的路径。这条路径的长度是k-1。
  • 祖先、子孙:在树中,如果有一条路径从结点M到结点N,那么M就称为N的祖先,而N称为M的子孙。
  • 结点的层数:规定树的根结点的层数为1,其余结点的层数等于它的双亲结点的层数加1。
  • 树的深度:树中所有结点的最大层数称为树的深度.
  • 树的度:树中各结点度的最大值称为该树的度。
  • 有序树和无序树:如果一棵树中结点的各子树从左到右是有次序的,即若交换了某结点各子树的相对位置,则构成不同的树,称这棵树为有序树;反之,则称为无序树。
  • 森林:零棵或有限棵不相交的树的集合称为森林。自然界中树和森林是不同的概念,但在数据结构中,树和森林只有很小的差别。任何一棵树,删去根结点就变成了森林。

2、二叉树

2.1、二叉树基本概念

  • 二叉树
    二叉树(Binary Tree)是一种每结点最多拥有2个子树的树结构,其中第1个子树被称为左子树,第2个子树被称为右子树。注意,当二叉树的结点个数为0时,我们称这个二叉树为空二叉树,记为Φ。二叉树是有序的,即若将其左、右子树颠倒,就成为另一棵不同的二叉树。即使树中结点只有一棵子树,也要区分它是左子树,还是右子树。因此二叉树具有五种基本形态。

  • 满二叉树
    在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子结点都在同一层上,这样的一棵二叉树称作满二叉树。(a)图就是一棵满二叉树,(b)图则不是满二叉树,因为该二叉树的D,F,G,H,I叶子结点未在同一层上。

  • 完全二叉树
    完全二叉树是一种叶子结点只能出现在最下层和次下层且最下层的叶子结点集中在树的左边的特殊二叉树。图5.5(a)所示为一棵完全二叉树,图5.4(b)和图5.5(b)都不是完全二叉树。对比图5.4(a)和图5.5(a)可以发现,满二叉树与完全二叉树存在如下关系:当树的深度相同时,若对树的结点按从上至下、从左到右的顺序进行编号,则在两种树上同一个位置上的结点的编号相同。显然,一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树。

  • 二叉树性质
    性质1 一棵非空二叉树的第i层上最多有2i-1个结点(i≥1)。
    性质2 一棵深度为k的二叉树中,最多具有2k-1个结点。
    性质3 对于一棵非空的二叉树,如果叶子结点数为n0,度数为2的结点数为n2,则有:n0=n2+1。
    性质4 具有n个结点的完全二叉树的深度k为[Log2n]
    性质5 对于具有n个结点的完全二叉树,如果按照从上至下和从左到右的顺序对二叉树中的所有结点从1开始顺序编号,则对于任意的序号为i的结点,有:
    (1)如果i>1,则序号为i的结点的父结点的序号为[插图];如果i=1,则该结点是根结点,无父结点。
    (2)如果2i≤n,则序号为i的结点的左子结点的序号为2i;如果2i>n,则序号为i的结点无左子结点。
    (3)如果2i+1≤n,则序号为i的结点的右子结点的序号为2i+1;如果2i+1>n,则序号为i的结点无右子结点。+1。

2.2、二叉树的存储结构

  • 顺序存储结构
    所谓二叉树的顺序存储,就是用一组连续的存储单元存放二叉树中的结点。一般是按照二叉树结点从上至下、从左到右的顺序存储。这样结点在存储位置上的前驱、后继关系并不一定就是它们在逻辑上的邻接关系,然而只有通过一些方法确定某结点在逻辑上的前驱结点和后继结点,这种存储才有意义。因此,依据二叉树的性质,完全二叉树和满二叉树采用顺序存储比较合适,树中结点的序号可以唯一地反映出结点之间的逻辑关系,这样既能够最大可能地节省存储空间,又可以利用数组元素的下标值确定结点在二叉树中的位置,以及结点之间的关系。

  • 链式存储结构
    所谓二叉树的链式存储结构是指用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。通常有下面两种形式。
    (1) 二叉链表存储
    链表中每个结点由三个域组成,除了数据域外,还有两个指针域,分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。结点的存储结构为:

    其中,data域存放某结点的数据信息;lchild与rchild分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或null表示)。
    二叉树链式存储的每个结点可描述为:
class Node<T>
{public Node<T> lChild;     //左孩子private T data;             //数据域public Node<T> rChild;     //右孩子public Node()              //构造函数,创建一个空节点{data = null;lChild = null;rChild = null;}public Node(T x)               //重载构造函数,创建一个数据值为x的节点{data = x;lChild = null;rChild = null;}
}

二叉链表也可以带头结点的方式存放:

在Java中描述二叉链表的关键是确定二叉树的根,代码如下。

class BinaryTree<T>
{public Node<T> root;       //根结点public BinaryTree()  //创建一棵空二叉树{this.root = new Node<T>();}public BinaryTree(T x)   //创建一棵以数据元素x为根结点的二叉树{this.root = new Node<T>(x);}//……
}

(2)三叉链表存储:
每个结点由四个域组成,具体结构为:

其中,data、lchild以及rchild三个域的意义同二叉链表结构,parent域为指向该结点双亲结点的指针。这种存储结构既便于查找孩子结点,又便于查找双亲结点,但是,相对于二叉链表存储结构而言,它增加了空间开销。
一棵二叉树的三叉链表表示:

尽管在二叉链表中无法由结点直接找到其双亲,但由于二叉链表结构灵活,操作方便,对于一般情况的二叉树,甚至比顺序存储结构还节省空间。因此,二叉链表是最常用的二叉树存储方式。

2.3、二叉树的基本操作及实现

  • 二叉树的基本操作:
class BinaryTree<T>
{private Node<T> root;public BinaryTree(){}      //创建一棵空二叉树public BinaryTree(T x){}   //创建一棵以数据元素x为根结点的二叉树/*在当前二叉树的parent结点中插入一个新的左子结点,
若已存在左子树,则将该左子树变成新左子结点的左孩子树*/public boolean insertLeft(T x, Node<T> parent){ }/*在当前二叉树的parent结点中插入一个新的右孩子结点,
若已存在右子树,则将该右子树变成新右孩子结点的左子树*/public boolean insertRight(Node<T> parent){ }//删除在当前二叉树的parent结点中的左子树public boolean deleteLeft(Node<T> parent){ }//删除在当前二叉树的parent结点中的右子树public boolean deleteRight(Node<T> parent){ }public boolean search(T x){ } //在当前二叉树中查找数据xpublic void traversal(int i){ }  //按某种方式遍历当前二叉树的全部结点public int getHeight(Node<T> parent){ }   //求当前二叉树的高度
}
  • 算法的实现:
    算法的实现依赖于具体的存储结构,当二叉树采用不同的存储结构时,上述各种操作的实现算法是不同的。下面讨论基于二叉链表存储结构的上述操作的实现算法。
    建立一棵空二叉树:
public BinaryTree()
{this.root = new Node<T>();  //创建根结点,该结点的数据域为空
}

生成一棵二叉树:

public BinaryTree(T x)   //创建一棵以数据元素x为根结点的二叉树
{this.root = new Node<T>(x);
}

向二叉树中插入一个左孩子结点:

//在当前二叉树的parent节点中插入一个新的左孩子结点,若已存在左子树,则将该左子树变成新左孩子结点的左子树
public boolean insertLeft(T x, Node<T> parent)
{if(parent==null)        return false;Node<T> p= new Node<T>(x);    //创建一个新结点if(parent.lChild==null)parent.lChild = p;   //将新结点直接设置到父结点的左孩子结点else{//先将父结点原来的左子树设置为新结点的左子树p.lChild = parent.lChild;//再将新结点设置到父结点的左孩子结点parent.lChild = p;}return true;
}
//注意,若要执行本操作,则必须先确定插入位置,即parent节点

删除二叉树的左子树:

//删除当前二叉树的parent结点中的左子树
public boolean deleteLeft(Node<T> parent)
{if(parent==null)        return false;else{parent.lChild=null;return true;}
}

2.4、二叉树的遍历

二叉树的遍历是指按照某种顺序访问二叉树中的每个结点,使每个结点被访问一次且仅被访问一次。
遍历是二叉树中经常要用到的一种操作。因为在实际应用问题中,常常需要按一定顺序对二叉树中的每个结点逐个进行访问,查找具有某一特点的结点,然后对这些满足条件的结点进行处理。
通过一次完整的遍历,可使二叉树中结点信息由非线性排列变为某种意义上的线性序列。也就是说,遍历操作使非线性结构线性化。
由二叉树的定义可知,一棵二叉树由根结点、根结点的左子树和根结点的右子树三部分组成。因此,只要依次遍历这三部分,就可以遍历整个二叉树。若以D、L、R分别表示访问根结点、遍历根结点的左子树、遍历根结点的右子树,则二叉树的遍历方式有六种:DLR、LDR、LRD、DRL、RDL和RLD。如果限定先左后右,则只有前三种方式,即DLR(称为先序遍历)、LDR(称为中序遍历)和LRD(称为后序遍历)。

  • 先序遍历(DLR)
    先序遍历的递归过程为:
    若二叉树为空,遍历结束,否则,
    (1)访问根结点;
    (2)先序遍历根结点的左子树;
    (3)先序遍历根结点的右子树。
public void preorder(Node<T> node)
{if(node==null) return;else{visit(node.getData());   //访问根结点preOrder(node.lChild);   //先序遍历左子树preOrder(node.rChild);   //先序遍历右子树}
}
  • 中序遍历(LDR)
    中序遍历的递归过程为:
    若二叉树为空,遍历结束,否则,
    (1)中序遍历根结点的左子树;
    (2)访问根结点;
    (3)中序遍历根结点的右子树。
public void inorder(Node<T> node)
{if(node==null) return;else{inorder(node.lChild);   //中序遍历左子树visit(node.getData());  //访问根结点inorder(node.rChild);   //中序遍历右子树}
}
  • 后序遍历(LRD)
    后序遍历的递归过程为:
    若二叉树为空,遍历结束,否则,
    (1)后序遍历根结点的左子树;
    (2)后序遍历根结点的右子树;
    (3)访问根结点。
public void postorder(Node<T> node)
{if(node==null) return;else{postorder(node.lChild);   //后序遍历左子树postorder(node.rChild);   //后序遍历右子树visit(node.getData());  //访问根结点}
}
  • 层次遍历
    二叉树的层次遍历,是指从二叉树的第一层(根结点)开始,从上至下逐层遍历,在同一层中,则按从左到右的顺序对结点逐个访问。
    由层次遍历的定义可以推知,在进行层次遍历时,对一层结点访问完后,再按照它们的访问次序对各个结点的左孩子和右孩子顺序访问,这样一层一层进行,先遇到的结点先访问,这与队列的操作原则比较吻合。因此,在进行层次遍历时,可设置一个队列结构,遍历从二叉树的根结点开始,首先将根结点进队列,然后从队头取出一个元素,每取一个元素,执行下面两个操作。
    (1)访问该元素所指结点。
    (2)若该元素所指结点的左、右孩子结点非空,则将该元素所指结点的左孩子结点和右孩子结点顺序进队。此过程不断进行,当队列为空时,二叉树的层次遍历结束。
public void levelOrder()
{Node<T>[] queue= new Node[this.maxNodes];//构造一个队列int front,rear;    //队首指针、队尾指针if (this.root==null) return;front=-1;      //队列暂时为空,队首指针不指向任何一个数组元素rear=0;        //队列暂时为空,队尾指针指向第一个数组元素queue[rear]=this.root;  //二叉树的根结点进队列while(front!=rear){front++;visit(queue[front].getData());    /*访问队首结点的数据域*//*将队首结点的左孩子结点进队列*/if (queue[front].lChild!=null){rear++;queue[rear]=queue[front].lChild;}/*将队首结点的右孩子结点进队列*/if (queue[front].rChild!=null){rear++;queue[rear]=queue[front].rChild;}}
}

2.5、完整代码

package com.young.tree;/*** <p>* Title:树节点:二叉链表结构* </p>** @Author: yangyongbing* @Date: 2023-04-18 13:25* @version: v1.0*/
public class Node<T> {public Node<T> lChild;private T data;public Node<T> rChild;public Node() {lChild=null;data=null;rChild=null;}public Node(T data) {this.data = data;this.lChild=null;this.rChild=null;}public Node<T> getlChild() {return lChild;}public void setlChild(Node<T> lChild) {this.lChild = lChild;}public T getData() {return data;}public void setData(T data) {this.data = data;}public Node<T> getrChild() {return rChild;}public void setrChild(Node<T> rChild) {this.rChild = rChild;}
}
package com.young.tree;/*** <p>* Title: 二叉树* </p>** @Author: yangyongbing* @Date: 2023-04-18* @version: v1.0*/
public class BinaryTree<T> {private final int maxNodes = 100;// 根节点public Node<T> root;// 创建一棵空二叉树public BinaryTree() {this.root = new Node<>();}// 创建一棵以数据元素x为根节点的二叉树public BinaryTree(T x) {this.root = new Node<>(x);}/*在当前二叉树的parent结点中插入一个新的左子结点,若已存在左子树,则将该左子树变成新左子结点的左孩子树*/public boolean addLeft(T x, Node<T> parent) {if (parent == null) {return false;}// 创建一个空节点Node<T> p = new Node<>(x);// 如果父节点的左子树为空,则直接将数据素x赋给父节点的左孩子节点if (parent.lChild != null) {// 将父节点的左子树赋给这个新节点左子节点p.lChild = parent.lChild;}// 将新节点赋给父节点的左孩子节点parent.lChild = p;return true;}/*在当前二叉树的parent结点中插入一个新的右子节点,若已存在右子树,则将该右子树变成新右子节点的右孩子树*/public boolean addRight(T x, Node<T> parent) {if (parent == null) {return false;}// 创建一个空节点Node<T> p = new Node<>(x);if (parent.rChild != null) {p.rChild = parent.rChild;}parent.rChild = p;return true;}// 删除当前二叉树的parent节点中的左子树public boolean deleteLeft(Node<T> parent) {if (parent == null) {return false;} else {parent.lChild = null;return true;}}// 删除当前二叉树的parent节点中的右子树public boolean deleteRight(Node<T> parent) {if (parent == null) {return false;} else {parent.rChild = null;return true;}}// 先序遍历public void preorder(Node<T> node) {if (node != null) {// 访问根节点visit(node.getData());// 先序遍历左子树preorder(node.getlChild());// 先序遍历右子树preorder(node.getrChild());}}// 中序遍历public void inorder(Node<T> node) {if (node != null) {// 中序遍历左子树inorder(node.lChild);// 访问根节点visit(node.getData());// 中序遍历右子树inorder(node.rChild);}}// 后序遍历public void postorder(Node<T> node) {if (node != null) {// 后续遍历左子树postorder(node.lChild);// 后续遍历右子树postorder(node.rChild);// 访问根节点visit(node.getData());}}// 按层次遍历public void levelOrder() {// 节点数组,用于存放节点Node<T>[] queue = new Node[this.maxNodes];if (this.root == null) {return;}// 定义队首和队尾指针int front, rear;// 队列为空,对首指针不指向任何一个数组元素front = -1;// 队列为空,对尾指针指向数组第一个位置rear = 0;// 根节点入队queue[rear] = this.root;while (front != rear) {// 访问对首节点的数据域front++;visit(queue[front].getData());// 左节点入队if (queue[front].lChild != null) {rear++;queue[rear] = queue[front].lChild;}// 右节点入队if (queue[front].rChild != null) {rear++;queue[rear] = queue[front].rChild;}}}private void visit(T x) {System.out.println(x);}// 在当前二叉树中查找数据xpublic boolean search(Node<T> node,T x) {if (node != null) {// 访问根节点T t = node.getData();if(x==t){return true;}// 先序遍历左子树search(node.getlChild(),x);// 先序遍历右子树search(node.getrChild(),x);}return false;}// 按某种方式遍历二叉树中的所有节点//按指定方式遍历二叉树//i=0表示先序遍历,=1表示中序遍历,=2表示后序遍历,=3表示层次遍历public void traversal(int i){switch(i){case 0: preorder(this.root);break;case 1: inorder(this.root);break;case 2: postorder(this.root);break;default: levelOrder();}}// 求当前二叉树的高度public int getHeight(Node<T> parent) {int lh,rh,max;if(parent!=null){lh=getHeight(parent.lChild);rh=getHeight(parent.rChild);max= Math.max(lh, rh);return max+1;}return 0;}
}

3、线索二叉树

3.1、定义

按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排列为一个线性序列。在该序列中,除第一个结点外,每个结点有且仅有一个直接前驱结点,除最后一个结点外,每个结点有且仅有一个直接后继结点。但是,二叉树中每个结点在这个序列中的直接前驱结点和直接后继结点是什么,二叉树的存储结构中并没有反映出来,只能在对二叉树遍历的动态过程中得到这些信息。为了保留结点在某种遍历序列中直接前驱和直接后继的位置信息,可以利用二叉树的二叉链表存储结构中的那些空指针域来指示。这些指向直接前驱结点和指向直接后继结点的指针被称为线索(thread),加了线索的二叉树称为线索二叉树。线索二叉树将为二叉树的遍历提供许多方便。

3.2、线索二叉树的结构

树形结构——JAVA实现相关推荐

  1. java树结构遍历_树形结构,java_树遍历统计总数,树形结构,java - phpStudy

    树遍历统计总数 { platformId: 3, areaId: "", areaName: "ROOT", parentAreaId: "" ...

  2. JAVA定义一个树形的结构_Java自定义树形结构

    Java自定义树形结构 Java自定义树形结构 为什么80%的码农都做不了架构师?>>> 树形结构 Java package com.zyl.comm; import java.ut ...

  3. 使用递归算法结合数据库解析成java树形结构

    使用递归算法结合数据库解析成java树形结构 1.准备表结构及对应的表数据 a.表结构: create table TB_TREE ( CID NUMBER not null, CNAME VARCH ...

  4. java 树状数据算法_使用递归算法结合数据库解析成Java树形结构的代码解析

    这篇文章主要介绍了使用递归算法结合数据库解析成Java树形结构的代码解析的相关资料,需要的朋友可以参考下 1.准备表结构及对应的表数据 a.表结构:create table TB_TREE ( CID ...

  5. java父子表_Java编程:将具有父子关系的数据库表数据转换为树形结构,支持无限层级...

    在平时的开发工作中,经常遇到这样一个场景,在数据库中存储了具有父子关系的数据,需要将这些数据以树形结构的形式在界面上进行展示.本文的目的是提供了一个通用的编程模型,解决将具有父子关系的数据转换成树形结 ...

  6. java组装树状结构数据集合_JAVA构建List集合为树形结构

    package com.zving.tree; import java.util.ArrayList; import java.util.List; /** * 树形结构实体类 * @author c ...

  7. java 构建树形结构_Java求助:如何建立一个树形结构

    在Java中如何实现一个如下的树形结构:root/|\year_2009year_2008year_2007,etc/|||month_1month_2month_1month_1|\|/\|day1 ...

  8. java 树结构_Java通用tree树形结构

    前言 现在大部分都是后端封装树形结构,第一次做的时候想从网上找通用,发现大部分都是要用类的get/set方法,不一样就要改,毕竟懒,改就改改,后来发现部门要,地区要,分类要,于是想着就把之前的用注解和 ...

  9. java实现处理无限层级树形结构

    树形结构在实际业务中是很经常遇到的,比如说机构.菜单.部门等等业务就会经常遇到层级关系.一般层级处理,有两种方式 (1)将所有的数据返回给前端,由前端处理,组装成树形结构,别担心,前端有组件的,只要后 ...

最新文章

  1. 在线作图|2分钟绘制一张箱线图
  2. Hadoop 核心编程之 HDFS 的文件操作
  3. mysql查看执行计划_如何查看MySQL的执行计划
  4. 使用Prometheus+Grafana 监控MySQL/MONGODB
  5. 浅谈疫情下的就业形势
  6. linux看dns解析的时间,curl测试dns解析时间
  7. SQL Server-SQL事务处理(Stransaction)
  8. Linux面试必备20个常用命令
  9. 以5‰的概率计算一个网络准确率达到99.9%的时间和迭代次数---实例三分类mnist 3,4,5
  10. tf.contrib.silm学习
  11. (转)隐藏在生活里的量化投资密码
  12. 计算机无法识别移动硬盘怎么办,电脑识别不出来移动硬盘怎么办
  13. GitHub上传教程,图文并茂
  14. java 护眼背景,设置Eclipse配色方案--设置不同背景色,有效护眼
  15. ReadMe 好看指南
  16. 逻辑运算符以及逻辑表达式
  17. 卓有成效的团队建设经验与见解 Team Leader你会带团队吗?
  18. 寒假算法训练1-J(分棍子,求最长棍子的数量,另外学习map的排序方法)
  19. php 计费系统设计,php超市收费系统
  20. 如何用企业微信做增长裂变?企业微信和个人微信的区别,怎么让“流”量变“留”量?

热门文章

  1. 惠普战x适合计算机专业吗,惠普战x锐龙版怎么样?电脑值得入手吗?
  2. 解放运维的双手,谈自动化运维管理平台设计
  3. 整理总结:《量化交易——如何建立自己的算法交易事业》
  4. 【新书推荐】【2018】有源集成天线的设计与应用
  5. 测试狗:冷冻电镜是什么?冷冻电镜技术的应用
  6. PAT——1121 Damn Single 甲级
  7. 3d 饼环图 echarts实现
  8. .sqlite后缀文件转为sql文件
  9. IT行业的魔力在哪里?98%的人都......
  10. linux bind升级,bind9.2升级bind9.9