精华内容
下载资源
问答
  • 多级结构金属镍的合成及其吸波性能研究,刘久荣,孔静,本文通过溶剂热反应法用丙二醇作为溶剂,在聚乙烯吡咯烷酮(PVP)的辅助下一步合成了单分散且具有多级结构的镍三维花状结构。样品�
  • 铂/镍多级结构纳米合金的制备及其对甲醇氧化的电催化性能,李杰,张东凤,在液相中用共还原法合成出了铂/镍(Pt/Ni)纳米合金多级结构材料,实验中发现有机表面活性剂在调控多级结构的形貌中起了关键作用....
  • 多级结构碳酸锰锂离子电池负极材料的制备及储锂性能研究,仲逸人,杨梅,碳酸锰材料作为新型锂离子电池负极材料而被深入研究。通过水热沉淀转化法制备多级结构碳酸锰材料,并研究了两种阴离子对材料形貌
  • 催化碳酸二甲酯合成的多级结构花状MgO催化剂的制备与表征,崔志民,郝静,碳酸二甲酯(DMC)是一种低污染、易生物降解、环境友好的绿色基础化工原料。酯交换法制备DMC是一条极具工业应用前景的绿色方法,因
  • 产品分类,多级的树状结构的论坛,邮件列表等许多地方我们都会遇到这样的问题:如何存储多级结构的数据?在PHP的应用中,提供后台数据存储的通常是关系型数据库,它能够保存大量的数据,提供高效的数据检索和更新...

    产品分类,多级的树状结构的论坛,邮件列表等许多地方我们都会遇到这样的问题:如何存储多级结构的数据?在PHP的应用中,提供后台数据存储的通常是关系型数据库,它能够保存大量的数据,提供高效的数据检索和更新服务。然而关系型数据的基本形式是纵横交错的表,是一个平面的结构,如果要将多级树状结构存储在关系型数据库里就需要进行合理的翻译工作。接下来我会将自己的所见所闻和一些实用的经验和大家探讨一下:

    层级结构的数据保存在平面的数据库中基本上有两种常用设计方法:

    1、毗邻目录模式(adjacency list model)

    2、预排序遍历树算法(modified preorder tree traversal algorithm)

    我不是计算机专业的,也没有学过什么数据结构的东西,所以这两个名字都是我自己按照字面的意思翻的,如果说错了还请多多指教。

    这两个东西听着好像很吓人,其实非常容易理解。这里我用一个简单食品目录作为我们的示例数据。 我们的数据结构是这样的

    以下是代码:

    Food
    |
    |---Fruit
    |    |
    |    |---Red
    |    |    |
    |    |    |--Cherry
    |    |
    |    |---Yellow
    |          |
    |          |--Banana
    |
    |---Meat
        |
        |--Beef
        |
        |--Pork
    

    为了照顾那些英文一塌糊涂的PHP爱好者

    Food:食物

    Fruit:水果

    Red:红色

    Cherry:樱桃

    Yellow:黄色

    Banana:香蕉

    Meat:肉类

    Beef:牛肉

    Pork:猪肉

    **毗邻目录模式(adjacency list model) **

    这种模式我们经常用到,很多的教程和书中也介绍过。我们通过给每个节点增加一个属性 parent 来表示这个 节点的父节点从而将整个树状结构通过平面的表描述出来。根据这个原则,例子中的数据可以转化成如下的表:

    以下是代码:

    +-----------------------+
    |   parent |    name    |
    +-----------------------+
    |          |    Food    |
    |   Food   |   Fruit    |
    |   Fruit  |    Green   |
    |   Green  |    Pear    |
    |   Fruit  |    Red     |
    |   Red    |    Cherry  |
    |   Fruit  |    Yellow  |
    |   Yellow |    Banana  |
    |   Food   |    Meat    |
    |   Meat   |    Beef    |
    |   Meat   |    Pork    |
    +-----------------------+
    

    我们看到 Pear 是Green的一个子节点,Green是Fruit的一个子节点。而根节点'Food'没有父节点。 为了简单地描述这个问题, 这个例子中只用了name来表示一个记录。 在实际的数据库中,你需要用数字的id来标示每个节点,数据库的表结构大概应该像这样:id, parent_id, name, description。

    有了这样的表我们就可以通过数据库保存整个多级树状结构了。

    显示多级树

    如果我们需要显示这样的一个多级结构需要一个递归函数。

    以下是代码:

    <?php
    // $parent is the parent of the children we want to see
    // $level is increased when we go deeper into the tree,
    //        used to display a nice indented tree
    function display_children($parent, $level)
    {
       // 获得一个 父节点 $parent 的所有子节点
       $result = mysql_query('SELECT name FROM tree '.
                              'WHERE parent="'.$parent.'";');
       // 显示每个子节点
       while ($row = mysql_fetch_array($result))
       {
           // 缩进显示节点名称
           echo str_repeat('  ',$level).$row['name']."n";
           //再次调用这个函数显示子节点的子节点
         
           display_children($row['name'], $level+1);
       }
    }
    ?>;
    

    对整个结构的根节点(Food)使用这个函数就可以打印出整个多级树结构,由于Food是根节点它的父节点是空的,所以这样调用: display_children('',0)。将显示整个树的内容:

    Food
    Fruit
     Red
      Cherry
     Yellow
      Banana
    Meat
     Beef
     Pork
    

    如果你只想显示整个结构中的一部分,比如说水果部分,就可以这样调用:display_children('Fruit',0); 几乎使用同样的方法我们可以知道从根节点到任意节点的路径。比如 Cherry 的路径是 "Food >; Fruit >; Red"。 为了得到这样的一个路径我们需要从最深的一级"Cherry"开始, 查询得到它的父节点"Red"把它添加到路径中, 然后我们再查询Red的父节点并把它也添加到路径中,以此类推直到最高层的"Food"

    以下是代码:

    <?php
    // $node 是那个最深的节点
    function get_path($node)
    {
       // 查询这个节点的父节点
       $result = mysql_query('SELECT parent FROM tree '.
                              'WHERE name="'.$node.'";');
       $row = mysql_fetch_array($result);
       // 用一个数组保存路径
       $path = array();
       // 如果不是根节点则继续向上查询
       // (根节点没有父节点)
       if ($row['parent']!='')
       {
           // the last part of the path to $node, is the name
           // of the parent of $node
           $path[] = $row['parent'];
           // we should add the path to the parent of this node
           // to the path
           $path = array_merge(get_path($row['parent']), $path);
       }
       // return the path
       return $path;
    }
    ?>;
    

    如果对"Cherry"使用这个函数:print_r(get_path('Cherry')),就会得到这样的一个数组了:

    Array
    (
      [0] =>; Food
      [1] =>; Fruit
      [2] =>; Red
    )
    

    接下来如何把它打印成你希望的格式,就是你的事情了。

    缺点:

    这种方法很简单,容易理解,好上手。但是也有一些缺点。主要是因为运行速度很慢,由于得到每个节点都需要进行数据库查询,数据量大的时候要进行很多查询才能完成一个树。另外由于要进行递归运算,递归的每一级都需要占用一些内存所以在空间利用上效率也比较低。

    **排序遍历树算法(modified preorder tree traversal algorithm) **

    现在让我们看一看另外一种不使用递归计算,更加快速的方法,这就是预排序遍历树算法(modified preorder tree traversal algorithm)

    这种方法大家可能接触的比较少,初次使用也不像上面的方法容易理解,但是由于这种方法不使用递归查询算法,有更高的查询效率。

    我们首先将多级数据按照下面的方式画在纸上,在根节点Food的左侧写上 1 然后沿着这个树继续向下 在 Fruit 的左侧写上 2 然后继续前进,沿着整个树的边缘给每一个节点都标上左侧和右侧的数字。最后一个数字是标在Food 右侧的 18。 在下面的这张图中你可以看到整个标好了数字的多级结构。(没有看懂?用你的手指指着数字从1数到18就明白怎么回事了。还不明白,再数一遍,注意移动你的手指)。

    这些数字标明了各个节点之间的关系,"Red"的号是3和6,它是 "Food" 1-18 的子孙节点。 同样,我们可以看到 所有左值大于2和右值小于11的节点 都是"Fruit" 2-11 的子孙节点

    以下是代码:

                                    1 Food 18
                                        |
                    +-------------------------------------------+
                    |                                           |
                2 Fruit 11                                    12 Meat 17
                    |                                           |
        +------------------------+                   +-----------------------+
        |                        |                   |                       |
     3 Red 6               7 Yellow 10            13 Beef 14            15 Pork 16
        |                        |
    4 Cherry 5               8 Banana 9
    

    这样整个树状结构可以通过左右值来存储到数据库中。继续之前,我们看一看下面整理过的数据表。 以下是代码:

    +-----------------------+-----+-----+
    |   parent |    name  | lft   | rgt |
    +-----------------------+-----+-----+
    |          |    Food    | 1   | 18  |
    |   Food   |   Fruit    | 2   | 11  |
    |   Fruit  |    Red     | 3   |  6  |
    |   Red    |    Cherry  | 4   |  5  |
    |   Fruit  |    Yellow  | 7   | 10  |
    |   Yellow |    Banana  | 8   |  9  |
    |   Food   |    Meat    | 12  | 17  |
    |   Meat   |    Beef    | 13  | 14  |
    |   Meat   |    Pork    | 15  | 16  |
    +-----------------------+-----+-----+
    

    注意:由于"left"和"right"在 SQL中有特殊的意义,所以我们需要用"lft"和"rgt"来表示左右字段。 另外这种结构中不再需要"parent"字段来表示树状结构。也就是 说下面这样的表结构就足够了。

    以下是代码:

    +------------+-----+-----+
    |    name    | lft | rgt |
    +------------+-----+-----+
    |    Food    | 1   | 18  |
    |   Fruit    | 2   | 11  |
    |    Red     | 3   |  6  |
    |    Cherry  | 4   |  5  |
    |    Yellow  | 7   | 10  |
    |    Banana  | 8   |  9  |
    |    Meat    | 12  | 17  |
    |    Beef    | 13  | 14  |
    |    Pork    | 15  | 16  |
    +------------+-----+-----+
    

    好了我们现在可以从数据库中获取数据了,例如我们需要得到"Fruit"项下的所有所有节点就可以这样写查询语句:

    SELECT * FROM tree WHERE lft BETWEEN 2 AND 11;

    这个查询得到了以下的结果。

    以下是代码:

    +------------+-----+-----+
    |    name    | lft | rgt |
    +------------+-----+-----+
    |   Fruit    | 2   | 11  |
    |    Red     | 3   |  6  |
    |    Cherry  | 4   |  5  |
    |    Yellow  | 7   | 10  |
    |    Banana  | 8   |  9  |
    +------------+-----+-----+
    

    看到了吧,只要一个查询就可以得到所有这些节点。为了能够像上面的递归函数那样显示整个树状结构,我们还需要对这样的查询进行排序。用节点的左值进行排序:

    SELECT * FROM tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC;

    剩下的问题如何显示层级的缩进了。

    以下是代码:

    <?php
    function display_tree($root)
    {
       // 得到根节点的左右值
       $result = mysql_query('SELECT lft, rgt FROM tree '.'WHERE name="'.$root.'";');
       $row = mysql_fetch_array($result);
       // 准备一个空的右值堆栈
       $right = array();
       // 获得根基点的所有子孙节点
       $result = mysql_query('SELECT name, lft, rgt FROM tree '.
                              'WHERE lft BETWEEN '.$row['lft'].' AND '.
                              $row['rgt'].' ORDER BY lft ASC;');
       // 显示每一行
       while ($row = mysql_fetch_array($result))
       {
           // only check stack if there is one
           if (count($right)>;0)
       {
               // 检查我们是否应该将节点移出堆栈
               while ($right[count($right)-1]<$row['rgt'])
       {
                   array_pop($right);
               }
           }
           // 缩进显示节点的名称
           echo str_repeat('  ',count($right)).$row['name']."n";
           // 将这个节点加入到堆栈中
           $right[] = $row['rgt'];
       }
    }
    ?>;
    

    如果你运行一下以上的函数就会得到和递归函数一样的结果。只是我们的这个新的函数可能会更快一些,因为只有2次数据库查询。

    要获知一个节点的路径就更简单了,如果我们想知道Cherry 的路径就利用它的左右值4和5来做一个查询。

    SELECT name FROM tree WHERE lft < 4 AND rgt >; 5 ORDER BY lft ASC;

    这样就会得到以下的结果:

    以下是代码:

    +------------+
    |    name    |
    +------------+
    |   Food     |
    |   Fruit    |
    |    Red     |
    +------------+
    

    那么某个节点到底有多少子孙节点呢?很简单,子孙总数=(右值-左值-1)/2

    descendants = (right – left - 1) / 2

    不相信?自己算一算啦。

    用这个简单的公式,我们可以很快的算出"Fruit 2-11"节点有4个子孙节点,而"Banana 8-9"节点没有子孙节点,也就是说它不是一个父节点了。

    很神奇吧?虽然我已经多次用过这个方法,但是每次这样做的时候还是感到很神奇。

    这的确是个很好的办法,但是有什么办法能够帮我们建立这样有左右值的数据表呢?这里再介绍一个函数给大家,这个函数可以将name和parent结构的表自动转换成带有左右值的数据表。

    以下是代码:

    <?php
    function rebuild_tree($parent, $left) {
       // the right value of this node is the left value + 1
       $right = $left+1;
       // get all children of this node
       $result = mysql_query('SELECT name FROM tree '.
                              'WHERE parent="'.$parent.'";');
       while ($row = mysql_fetch_array($result)) {
           // recursive execution of this function for each
           // child of this node
           // $right is the current right value, which is
           // incremented by the rebuild_tree function
           $right = rebuild_tree($row['name'], $right);
       }
       // we've got the left value, and now that we've processed
       // the children of this node we also know the right value
       mysql_query('UPDATE tree SET lft='.$left.', rgt='.
                    $right.' WHERE name="'.$parent.'";');
       // return the right value of this node + 1
       return $right+1;
    }
    ?>;
    

    当然这个函数是一个递归函数,我们需要从根节点开始运行这个函数来重建一个带有左右值的树 rebuild_tree('Food',1);

    这个函数看上去有些复杂,但是它的作用和手工对表进行编号一样,就是将立体多层结构的转换成一个带有左右值的数据表。

    那么对于这样的结构我们该如何增加,更新和删除一个节点呢?

    增加一个节点一般有两种方法:

    第一种,保留原有的name 和parent结构,用老方法向数据中添加数据,每增加一条数据以后使用rebuild_tree函数对整个结构重新进行一次编号。

    第二种,效率更高的办法是改变所有位于新节点右侧的数值。举例来说:我们想增加一种新的水果"Strawberry"(草莓)它将成为"Red"节点的最后一个子节点。首先我们需要为它腾出一些空间。"Red"的右值应当从6改成8,"Yellow 7-10 "的左右值则应当改成 9-12。 依次类推我们可以得知,如果要给新的值腾出空间需要给所有左右值大于5的节点 (5 是"Red"最后一个子节点的右值) 加上2。 所以我们这样进行数据库操作:

    UPDATE tree SET rgt=rgt+2 WHERE rgt>;5;

    UPDATE tree SET lft=lft+2 WHERE lft>;5;

    这样就为新插入的值腾出了空间,现在可以在腾出的空间里建立一个新的数据节点了, 它的左右值分别是6和7 INSERT INTO tree SET lft=6, rgt=7, name='Strawberry';

    再做一次查询看看吧!怎么样?很快吧。

    好了,现在你可以用两种不同的方法设计你的多级数据库结构了,采用何种方式完全取决于你个人的判断,但是对于层次多数量大的结构我更喜欢第二种方法。如果查询量较小但是需要频繁添加和更新的数据,则第一种方法更为简便。

    另外,如果数据库支持的话 你还可以将rebuild_tree()和 腾出空间的操作写成数据库端的触发器函数, 在插入和更新的时候自动执行, 这样可以得到更好的运行效率, 而且你添加新节点的SQL语句会变得更加简单。

    转载于:https://my.oschina.net/knife2013/blog/518253

    展开全文
  • 使用xlrd解析excel的多级结构构建多叉树和结点结构由于要支持多级嵌套的表结构, 所以单纯的按照列的顺序来解析每行数据肯定达不到需求。所以约定Excel表头结构, 如果一个属性包含二级属性,则在该属性下新建一行表头...

    使用xlrd解析excel的多级结构

    构建多叉树和结点结构

    由于要支持多级嵌套的表结构, 所以单纯的按照列的顺序来解析每行数据肯定达不到需求。所以约定

    Excel表头结构, 如果一个属性包含二级属性,则在该属性下新建一行表头,表明二级属性名称

    如下图所示:

    示例图片

    然后按照表头结构,构建一个多叉树,每行数据解析的时候遍历多叉树结构解析。

    首先构建多叉树和数的结点

    class node:
        def __init__(self, des, x, y):
            self._des = des
            self._coordinate = [x, y]
            self._children = []
        def getDes(self):
            return self._des
        def getCoordinate(self):
            return self._coordinate
        def getChildren(self):
            return self._children
        def addChild(self, node):
            self._children.append(node)
    
    class tree:
        def __init__(self):
            self._head = node("head", -1, -1)
        def addChild(self, node):
            self._head.addChild(node)
        def getHead(self):
            return self._head

    根据Excel表中的合并单元格构建树

    # 处理Excel文件
    def process_excel(src):
        global sheet
        global MergePoints
        global text
    
        data = open_excel(src)
        sheet = data.sheets()[0]
        n_rows = sheet.nrows #总行数
        n_cols = sheet.ncols #总列数
        MergePoints = generateMergePoints(sheet.merged_cells)
        # 生成树状解析目录
        tree = generateTree(n_rows, n_cols) 
        # 根据树结构解析Excel表
        rowMin = getStartRow()
        for row in range(rowMin, n_rows):
            text = text + "\t{"
            traversingByTree(tree.getHead(), sheet.row_values(row))
            if row < n_rows - 1:
                text = text + "\n"
    

    MergePoints是一个列表,包含所有属于合并单元格的单元

    def generateMergePoints(merges):
        points = []
        for (x, xMax, y, yMax) in merges:
            for i in range(x,xMax):
                for j in range(y,yMax):
                    points.append([i, j])
        return points

    然后是树的生成,这个也是整个程序的核心,比较麻烦一些。本来我是定义的tree = tree(), 但是python报错了说是引用了一个未赋值的变量,这点我感觉很不智能,因为它在构建tree对象的时候没有首先查找我的类定义,而是在当前的方法体内寻找tree变量,可能这么设计有其他的需求吧,暂时换了个名字叫structTree。这个方法是从(0,0)开始遍历Excel的表头,如果有中文注释表头或者其他需求,请把row修改为其他值。

    注意: 在python中下标都是从0开始的,所以解析Excel时行跟列也是从0开始遍历的。

    def generateTree(rowMax, colMax):
        structTree = tree()
        row = 0
        for col in range(0, colMax):
            point = [row, col]
            endCol = col
            treeAddNodes(structTree, row, col, endCol)
        return structTree

    递归遍历表头生成树结构

    遍历顺序,如图所示,可以参考二叉树的前项遍历+层次遍历

    流程图

    参数解析:father:接下来遍历的结点的父节点。row, col:接下来遍历结点的坐标。endCol:下次遍历结点所属单元格的结束列坐标,如果不是合并单元格,则为遍历结点的列坐标。

    def treeAddNodes(father, row, col, endCol):
        global sheet
        global MergePoints
        point = [row, col]
        if not isPointInMergePoints(point):
            if col < endCol:
                # 遍历叶子的邻接点
                addNodes(father, row, col)
                treeAddNodes(father, row, col + 1, endCol)
            else :
                addNodes(father, row, col)
                return
        else:
            if not isHeadOfMergePoints(point):
                if col < endCol:
                    # 合并单元格的非头部结点只遍历不解析
                    treeAddNodes(father, row, col + 1, endCol)
            else:
                # update endCol
                newEndCol = getMergePointsEndCol(point)
                newNode = addNodes(father, row, col)
                # 合并单元格的头部结点子节点遍历
                treeAddNodes(newNode, row + 1, col, newEndCol)
                # 合并单元格的头部结点的邻接点遍历
                treeAddNodes(father, row, col + 1, endCol)
    
    def addNodes(father, row, col):
        global sheet
        des = sheet.cell_value(row, col)
        newNode = node(des, row, col)
        father.addChild(newNode)
        return newNode
    
    def isPointInMergePoints(point):
        global MergePoints
        for p in MergePoints:
            if point[0] == p[0] and point[1] == p[1]:
                return True
        return False
    
    def isHeadOfMergePoints(point):
        global sheet
        if isPointInMergePoints(point) and sheet.cell(point[0], point[1]).ctype != 0:
            return True
        return False
    
    # 获取当前单元格所在合并单元格的结束列坐标
    def getMergePointsEndCol(point):
        global sheet
        for [row, rowMax, col, colMax] in sheet.merged_cells:
            if point[0] == row and point[1] == col:
                return colMax - 1

    最后遍历树,解析Excel每行数据

    def traversingByTree(node, row_values):
        global sheet
        global text
        if node.getChildren() == None:
            return
        else :
            for child in node.getChildren():
                if child.getChildren():
                    text = text + child.getDes() + " = {"
                    traversingByTree(child, row_values)
                else :
                    [row, col] = child.getCoordinate()
                    if row_values[col] != "":
                        if isinstance(row_values[col], float):
                            text = text + child.getDes() + " = " + str(int(row_values[col])) + ", "
                        else :
                            text = text + child.getDes() + " = " + row_values[col] + ","
    
            text = text + "}, "

    解析结果

    解析出来的表结构如下:

    local config = {
        {index = 1, atk = {attr1 = 2, attr2 = 3, }, pcis = {attr3 = 4, attr4 = 5, }, dungeon = {gender = 6, dungeonInfo = {test3 = {test1 = 7, test2 = 8, }, aboutDungeon = {dungeonID = 9, }, }, }, }, 
        {index = 32, atk = {attr1 = 23, attr2 = 54, }, pcis = {attr3 = 5, attr4 = 6, }, dungeon = {gender = "男",dungeonInfo = {test3 = {test1 = 79, test2 = 45, }, aboutDungeon = {dungeonID = 12, }, }, }, }, 
    }
    return config

    源代码

    Readme里面有介绍使用方法

    点我下载

    展开全文
  • 第5章 ORACLE体系结构-数据库篇;为了避免控制文件与日志文件单点故障造成数据库无法使用你必须为oracle添加额外的控制与日志文件 由于日志文件组数量过少造成的性能问题日志组不能快速切换 此性能问题将造成数据库...
  • 通过对共轴电纺内流体溶液浓度和流速的调控得到4种具有不同内部结构的TiO2微纳米纤维,即具有“微孔”、“囊泡”、“竹节”和“管”状结构的TiO2微纳米纤维,实现了对纤维内部结构的有效控制,对于新型仿生中空纤维的...
  • 首先对指纹中的每个细节点定义具有很好区分度的子结构,根据这些子结构计算相似度并筛选出可能的参考点对。然后利用它们之间的边角关系等结构信息实施奖惩得分制度,根据事先设定的阈值,得分较高的参考点对被保留...
  • 产品分类,多级的树状结构的论坛,邮件列表等许多地方我们都会遇到这样的问题:如何存储多级结构的数据?在PHP的应用中,提供后台数据存储的通常是关系型数据库,它能够保存大量的数据,提供高效的数据检索和更新...

    产品分类,多级的树状结构的论坛,邮件列表等许多地方我们都会遇到这样的问题:如何存储多级结构的数据?在PHP的应用中,提供后台数据存储的通常是关系型数据库,它能够保存大量的数据,提供高效的数据检索和更新服务。然而关系型数据的基本形式是纵横交错的表,是一个平面的结构,如果要将多级树状结构存储在关系型数据库里就需要进行合理的翻译工作。接下来我会将自己的所见所闻和一些实用的经验和大家探讨一下: 

    层级结构的数据保存在平面的数据库中基本上有两种常用设计方法: 

    1、毗邻目录模式(adjacency list model) 

    2、预排序遍历树算法(modified preorder tree traversal algorithm) 

    我不是计算机专业的,也没有学过什么数据结构的东西,所以这两个名字都是我自己按照字面的意思翻的,如果说错了还请多多指教。 
    这两个东西听着好像很吓人,其实非常容易理解。这里我用一个简单食品目录作为我们的示例数据。 

    我们的数据结构是这样的 

    以下是代码: 

    Food
    |
    |---Fruit
    |    |
    |    |---Red
    |    |    |
    |    |    |--Cherry
    |    |
    |    |---Yellow
    |          |
    |          |--Banana
    |
    |---Meat
         |
         |--Beef
         |
         |--Pork
    



    为了照顾那些英文一塌糊涂的PHP爱好者 
    Food:食物 
    Fruit:水果 
    Red:红色 
    Cherry:樱桃 
    Yellow:黄色 
    Banana:香蕉 
    Meat:肉类 
    Beef:牛肉 
    Pork:猪肉 


    毗邻目录模式(adjacency list model) 
    这种模式我们经常用到,很多的教程和书中也介绍过。我们通过给每个节点增加一个属性 parent 来表示这个节点的父节点从而将整个树状结构通过平面的表描述出来。根据这个原则,例子中的数据可以转化成如下的表: 

    以下是代码: 

    +-----------------------+
    |   parent |    name    |
    +-----------------------+
    |          |    Food    |
    |   Food   |   Fruit    |
    |   Fruit  |    Green   |
    |   Green  |    Pear    |
    |   Fruit  |    Red     |
    |   Red    |    Cherry  |
    |   Fruit  |    Yellow  |
    |   Yellow |    Banana  |
    |   Food   |    Meat    |
    |   Meat   |    Beef    |
    |   Meat   |    Pork    |
    +-----------------------+
    
    




    我们看到 Pear 是Green的一个子节点,Green是Fruit的一个子节点。而根节点'Food'没有父节点。 为了简单地描述这个问题, 这个例子中只用了name来表示一个记录。 在实际的数据库中,你需要用数字的id来标示每个节点,数据库的表结构大概应该像这样:id, parent_id, name, description。 
    有了这样的表我们就可以通过数据库保存整个多级树状结构了。 

    显示多级树 
    如果我们需要显示这样的一个多级结构需要一个递归函数。 

    以下是代码: 

    <?php
    
    // $parent is the parent of the children we want to see
    
    // $level is increased when we go deeper into the tree,
    
    //        used to display a nice indented tree
    
    function display_children($parent, $level) 
    {
    
       // 获得一个 父节点 $parent 的所有子节点
    
       $result = mysql_query('SELECT name FROM tree '.
    
                              'WHERE parent="'.$parent.'";');
    
       // 显示每个子节点
       while ($row = mysql_fetch_array($result)) 
       {
           // 缩进显示节点名称
           echo str_repeat('  ',$level).$row['name']."n";
           //再次调用这个函数显示子节点的子节点
           display_children($row['name'], $level+1);
       }
    }
    
    ?>;
    
    



    对整个结构的根节点(Food)使用这个函数就可以打印出整个多级树结构,由于Food是根节点它的父节点是空的,所以这样调用: display_children('',0)。将显示整个树的内容: 

    Food 
    Fruit 
     Red
      Cherry 
     Yellow 
      Banana 
    Meat 
     Beef 
     Pork 
    
    


    如果你只想显示整个结构中的一部分,比如说水果部分,就可以这样调用:display_children('Fruit',0); 

    几乎使用同样的方法我们可以知道从根节点到任意节点的路径。比如 Cherry 的路径是 "Food >; Fruit >; Red"。 为了得到这样的一个路径我们需要从最深的一级"Cherry"开始, 查询得到它的父节点"Red"把它添加到路径中, 然后我们再查询Red的父节点并把它也添加到路径中,以此类推直到最高层的"Food" 

    以下是代码: 

    <?php
    
    // $node 是那个最深的节点
    function get_path($node) 
    {
       // 查询这个节点的父节点
       $result = mysql_query('SELECT parent FROM tree '.
                              'WHERE name="'.$node.'";');
       $row = mysql_fetch_array($result);
       // 用一个数组保存路径
       $path = array();
       // 如果不是根节点则继续向上查询
       // (根节点没有父节点)
       if ($row['parent']!='') 
       {
           // the last part of the path to $node, is the name
           // of the parent of $node
           $path[] = $row['parent'];
           // we should add the path to the parent of this node
           // to the path
           $path = array_merge(get_path($row['parent']), $path);
       }
       // return the path
       return $path;
    }
    
    ?>;
    
    



    如果对"Cherry"使用这个函数:print_r(get_path('Cherry')),就会得到这样的一个数组了: 

    Array 
    ( 
      [0] =>; Food 
    
      [1] =>; Fruit 
    
      [2] =>; Red 
    ) 
    
    


    接下来如何把它打印成你希望的格式,就是你的事情了。 

    缺点: 
    这种方法很简单,容易理解,好上手。但是也有一些缺点。主要是因为运行速度很慢,由于得到每个节点都需要进行数据库查询,数据量大的时候要进行很多查询才能完成一个树。另外由于要进行递归运算,递归的每一级都需要占用一些内存所以在空间利用上效率也比较低。 

    现在让我们看一看另外一种不使用递归计算,更加快速的方法,这就是预排序遍历树算法(modified preorder tree traversal algorithm) 
    这种方法大家可能接触的比较少,初次使用也不像上面的方法容易理解,但是由于这种方法不使用递归查询算法,有更高的查询效率。 

    我们首先将多级数据按照下面的方式画在纸上,在根节点Food的左侧写上 1 然后沿着这个树继续向下 在 Fruit 的左侧写上 2 然后继续前进,沿着整个树的边缘给每一个节点都标上左侧和右侧的数字。最后一个数字是标在Food 右侧的 18。 在下面的这张图中你可以看到整个标好了数字的多级结构。(没有看懂?用你的手指指着数字从1数到18就明白怎么回事了。还不明白,再数一遍,注意移动你的手指)。 
    这些数字标明了各个节点之间的关系,"Red"的号是3和6,它是 "Food" 1-18 的子孙节点。 同样,我们可以看到 所有左值大于2和右值小于11的节点 都是"Fruit" 2-11 的子孙节点 

    以下是代码: 

                                    1 Food 18
                                        |
                    +-------------------------------------------+
                    |                                                       |
                2 Fruit 11                                    12 Meat 17
                    |                                                       |
        +------------------------+                   +-----------------------+
        |                                |                   |                              |
     3 Red 6               7 Yellow 10         13 Beef 14            15 Pork 16
        |                                |
    4 Cherry 5               8 Banana 9
    



    这样整个树状结构可以通过左右值来存储到数据库中。继续之前,我们看一看下面整理过的数据表。 

    以下是代码: 

    +-----------------------+-----+-----+
    |   parent |    name  | lft   | rgt |
    +-----------------------+-----+-----+
    |              |    Food    | 1   | 18  |
    |   Food   |   Fruit      | 2   | 11  |
    |   Fruit    |    Red      | 3   |  6  |
    |   Red     |    Cherry  | 4   |  5  |
    |   Fruit    |    Yellow  | 7   | 10  |
    |   Yellow |    Banana | 8   |  9  |
    |   Food   |    Meat     | 12  | 17  |
    |   Meat   |    Beef     | 13  | 14  |
    |   Meat   |    Pork     | 15  | 16  |
    +-----------------------+-----+-----+
    



    注意:由于"left"和"right"在 SQL中有特殊的意义,所以我们需要用"lft"和"rgt"来表示左右字段。 另外这种结构中不再需要"parent"字段来表示树状结构。也就是 说下面这样的表结构就足够了。 

    以下是代码: 

    +------------+-----+-----+
    |    name    | lft | rgt |
    +------------+-----+-----+
    |    Food    | 1   | 18  |
    |   Fruit      | 2   | 11  |
    |    Red      | 3   |  6  |
    |    Cherry  | 4   |  5  |
    |    Yellow  | 7   | 10  |
    |    Banana | 8   |  9  |
    |    Meat     | 12  | 17  |
    |    Beef     | 13  | 14  |
    |    Pork     | 15  | 16  |
    +------------+-----+-----+
    
    



    好了我们现在可以从数据库中获取数据了,例如我们需要得到"Fruit"项下的所有所有节点就可以这样写查询语句: 
    SELECT * FROM tree WHERE lft BETWEEN 2 AND 11; 
    这个查询得到了以下的结果。 

    以下是代码: 

    +------------+-----+-----+
    |    name    | lft | rgt |
    +------------+-----+-----+
    |   Fruit    | 2   | 11  |
    |    Red     | 3   |  6  |
    |    Cherry  | 4   |  5  |
    |    Yellow  | 7   | 10  |
    |    Banana  | 8   |  9  |
    +------------+-----+-----+
    
    




    看到了吧,只要一个查询就可以得到所有这些节点。为了能够像上面的递归函数那样显示整个树状结构,我们还需要对这样的查询进行排序。用节点的左值进行排序: 

    SELECT * FROM tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC; 


    剩下的问题如何显示层级的缩进了。 

    以下是代码: 

    <?php
    function display_tree($root) 
    {
       // 得到根节点的左右值
       $result = mysql_query('SELECT lft, rgt FROM tree '.'WHERE name="'.$root.'";');
       $row = mysql_fetch_array($result);
       // 准备一个空的右值堆栈
       $right = array();
       // 获得根基点的所有子孙节点
       $result = mysql_query('SELECT name, lft, rgt FROM tree '.
                              'WHERE lft BETWEEN '.$row['lft'].' AND '.
                              $row['rgt'].' ORDER BY lft ASC;');
       // 显示每一行
       while ($row = mysql_fetch_array($result)) 
       {
           // only check stack if there is one
           if (count($right)>;0) 
       {
               // 检查我们是否应该将节点移出堆栈
               while ($right[count($right)-1]<$row['rgt']) 
       {
                   array_pop($right);
               }
    
           }
    
           // 缩进显示节点的名称
           echo str_repeat('  ',count($right)).$row['name']."n";
           // 将这个节点加入到堆栈中
           $right[] = $row['rgt'];
       }
    
    }
    
    ?>;
    
    



    如果你运行一下以上的函数就会得到和递归函数一样的结果。只是我们的这个新的函数可能会更快一些,因为只有2次数据库查询。 

    要获知一个节点的路径就更简单了,如果我们想知道Cherry 的路径就利用它的左右值4和5来做一个查询。 

    SELECT name FROM tree WHERE lft < 4 AND rgt >; 5 ORDER BY lft ASC; 

    这样就会得到以下的结果: 

    以下是代码: 

    +------------+
    |    name    |
    +------------+
    |   Food     |
    |   Fruit    |
    |    Red     |
    +------------+
    
    



    那么某个节点到底有多少子孙节点呢?很简单,子孙总数=(右值-左值-1)/2 
    descendants = (right – left - 1) / 2 
    不相信?自己算一算啦。 
    用这个简单的公式,我们可以很快的算出"Fruit 2-11"节点有4个子孙节点,而"Banana 8-9"节点没有子孙节点,也就是说它不是一个父节点了。 

    很神奇吧?虽然我已经多次用过这个方法,但是每次这样做的时候还是感到很神奇。 

    这的确是个很好的办法,但是有什么办法能够帮我们建立这样有左右值的数据表呢?这里再介绍一个函数给大家,这个函数可以将name和parent结构的表自动转换成带有左右值的数据表。 

    以下是代码: 

    <?php
    function rebuild_tree($parent, $left) {
       // the right value of this node is the left value + 1
       $right = $left+1;
    
       // get all children of this node
       $result = mysql_query('SELECT name FROM tree '.
                              'WHERE parent="'.$parent.'";');
    
       while ($row = mysql_fetch_array($result)) {
    
           // recursive execution of this function for each
    
           // child of this node
    
           // $right is the current right value, which is
    
           // incremented by the rebuild_tree function
    
           $right = rebuild_tree($row['name'], $right);
    
       }
    
    
    
       // we've got the left value, and now that we've processed
    
       // the children of this node we also know the right value
    
       mysql_query('UPDATE tree SET lft='.$left.', rgt='.
    
                    $right.' WHERE name="'.$parent.'";');
    
    
    
       // return the right value of this node + 1
    
       return $right+1;
    
    }
    
    ?>;
    
    



    当然这个函数是一个递归函数,我们需要从根节点开始运行这个函数来重建一个带有左右值的树 

    rebuild_tree('Food',1); 

    这个函数看上去有些复杂,但是它的作用和手工对表进行编号一样,就是将立体多层结构的转换成一个带有左右值的数据表。 

    那么对于这样的结构我们该如何增加,更新和删除一个节点呢? 

    增加一个节点一般有两种方法: 

    第一种,保留原有的name 和parent结构,用老方法向数据中添加数据,每增加一条数据以后使用rebuild_tree函数对整个结构重新进行一次编号。 

    第二种,效率更高的办法是改变所有位于新节点右侧的数值。举例来说:我们想增加一种新的水果"Strawberry"(草莓)它将成为"Red"节点的最后一个子节点。首先我们需要为它腾出一些空间。"Red"的右值应当从6改成8,"Yellow 7-10 "的左右值则应当改成 9-12。 依次类推我们可以得知,如果要给新的值腾出空间需要给所有左右值大于5的节点 (5 是"Red"最后一个子节点的右值) 加上2。 所以我们这样进行数据库操作: 

    UPDATE tree SET rgt=rgt+2 WHERE rgt>;5; 
    UPDATE tree SET lft=lft+2 WHERE lft>;5; 

    这样就为新插入的值腾出了空间,现在可以在腾出的空间里建立一个新的数据节点了, 它的左右值分别是6和7 

    INSERT INTO tree SET lft=6, rgt=7, name='Strawberry'; 

    再做一次查询看看吧!怎么样?很快吧。 

    好了,现在你可以用两种不同的方法设计你的多级数据库结构了,采用何种方式完全取决于你个人的判断,但是对于层次多数量大的结构我更喜欢第二种方法。如果查询量较小但是需要频繁添加和更新的数据,则第一种方法更为简便。 

    另外,如果数据库支持的话 你还可以将rebuild_tree()和 腾出空间的操作写成数据库端的触发器函数, 在插入和更新的时候自动执行, 这样可以得到更好的运行效率, 而且你添加新节点的SQL语句会变得更加简单。

     

     

     

    方法二:

     

    关于标记任意的级别数据,我还是赞同采取编码标记法
    比如,每级数据为四位数,饱合值9999,在编号存取方面,采用VChar值
    “Num.”四位作为前缀,之后是一级编码,二级编码,三级编码。。。比如一条信息在第四级13号,那其编号就是“Num.0001000100010013”
    递归列树则基础于检索时的条件限制,例如用“Num.xxxx%”作为关键字检索第一级的所有数据量,如果要把某一类置于另一个父类,只需要检索“Num.xxxxxxxx...”将前面的“Num.xxxx...”替换为父类的ID就OK了
    另,有两点需要注意:
    第一,这张数据表要有一个Max值表辅助,也就是要通过一个Max值,来记录每一个类已经存储的最大值;
    第二,删除数据时不能真的删除,而是打上删除标记,在插入新纪录时update,有效的节约资源

    本标记看似采用大数标记,其实属字串操作,不会耗太多的CPU资源,而设定索引后,配合左端定制右边通配符的条件检索,可以获得很高的效率

     

    方法二:

    无限级分类排序算法

    正在写一带分类的程序,基本构思如下:
    每级分类递增两位数字,这样,每级分类的数目限定在100个之间,分类方法主要为编码法;
    示例:
    一级分类:01,02,03
    二级分类:0101,0102,0103,0201,0202........
    三级分类:010101,010102,010103,010104..........

    数据库查询时使用 like '01%'就可得到一级分类01下的所有子分类,非常方便!
    如果要列出所有分类的树型结构,只需用一条语句select * from pro_class order by code,再稍微处理一下就可。(其中,pro_class为产品分类表,code为类别编码)。


    设计的数据库结构如下:

    id:                    类别id,主键
    classname:         类名
    classcode:          类别编码
    parent:             父id
    left_child:          最左孩子id(或第一个孩子)
    right_sibling:      右兄弟id
    layer:                层级(第一级类别为1,第2级类别2,以此类推)


    顺便说明一点,我们公司采用的就是这样的编码

    所以在输入的时候不会被轻易注入,只要检测好长度就可以了

    比如一级就是两个长度,就是两个多一个就提示出错就可以了

     

    方法三:

    递归调用,恩路如下:

    表为两张,一张分类表,一张信息表。
    信息表如下:

      `ID` int(10) unsigned NOT NULL auto_increment,
      `cID` tinyint(3) unsigned NOT NULL default '0',
      `title` varchar(255) NOT NULL default 'No Title',
      `content` mediumtext NOT NULL,

    最简单的无限级分类数据表,只是设置一个parentID来判断父ID
    数据表如下:

      `cID` tinyint(3) unsigned NOT NULL auto_increment,
      `parentID` tinyint(3) unsigned NOT NULL default '0',
      `order` tinyint(3) NOT NULL default '0',
      `name` varchar(255) NOT NULL default '',

    这样可以根据cID = parentID来判断上一级内容,运用递归至最顶层。

    将数据库里的数据存成一个二维数组,然后放到一个文件中去,用的时候直接将这个php文件引入,使用其中缓存下来的数组,用数组来进行如上的一系统运算。我作了一个600个分类,4层节点的表,进行了一下对比,直接操作用了近3秒才算出树形列表,而用数组,只花了0.06秒左右。

     

    以上是我在网上找的几种用数据库保存多级结构的数据的方法。

     

    展开全文
  • 最近新项目的需求给我出了个难题,让我读取树形结构的对象来构筑悬浮响应式的多级菜单,因为用的是ng2框架,本来打算使用ng2-tree作为插件,可是这个插件对外开放的接口太少了,连样式接口都没有,只能用默认样式,...

    最近新项目的需求给我出了个难题,让我读取树形结构的对象来构筑悬浮响应式的多级菜单,因为用的是ng2框架,本来打算使用ng2-tree作为插件,可是这个插件对外开放的接口太少了,连样式接口都没有,只能用默认样式,唯有样式客户决不妥协,无奈之下只能想到用原生js的dom操作来实现。以下是代码

    js部分,主要用递归方法构筑树形结构菜单:

     

     <script>
      //树形结构每个节点结构基本相同
      var data = {
        id: "01",
        value: "维度管理",
        children: [
          {
            id: "11",
            value: "岗位",
            children: []
          },
          {
            id: "12",
            value: "部门",
            children: [
              {
                id: "121",
                value: "信息部",
                children: []
              },
              {
                id: "122",
                value: "营运部",
                children: [
                  {
                    id: "1221",
                    value: "营运条例",
                    children: []
                  },
                  {
                    id: "1222",
                    value: "运营管理",
                    children: []
                  },
                  {
                    id: "1223",
                    value: "运营规范",
                    children: []
                  }
                ]
              },
              {
                id: "123",
                value: "质量部",
                children: []
              },
              {
                id: "124",
                value: "创新部",
                children: []
              },
              {
                id: "125",
                value: "销售部",
                children: []
              }
            ]
          },
          {
            id: "13",
            value: "集团",
            children: []
          },
          {
            id: "14",
            value: "分公司",
            children: []
          }
        ]
      };
      //调用方法
      valueSet(data, "dimension-tree");
      //data可替换为动态获取的数据
      //例如
      // private loadDimension(url: string) {
      // return this.httpServiceService.getHttp(url).subscribe(
      // res => {
      // this.valueSet(res, "dimension-tree");
      // },
      // error => {
      // console.log('错误', error);
      // }
      // );
      // }
      function valueSet(dataObject, id) {
        if (dataObject.children.length > 0) {
          for (i in dataObject.children) {
            this.DomEdt(id, dataObject.children[i]);
            this.valueSet(dataObject.children[i], dataObject.children[i].id);
          }
        }
      }
      //DOM操作
      function DomEdt(id, obj) {
        var li = document.createElement("li");
        if (document.getElementById(id)) {
          document.getElementById(id).appendChild(li);
        }
        var a = document.createElement("a");
        a.className = "dimensionA";
        a.textContent = obj.value;
        a.onclick = this.Onclick;
        li.appendChild(a);
        li.className = "dimensionLi";
        var ul = document.createElement("ul");
        li.appendChild(ul);
        ul.id = obj.id;
        ul.className = "dimensionUl";
        // ul.style.cssText = 'display:none';
      }
      //节点绑定事件,可获取节点相关内容
      function Onclick(e) {
        console.log(e.target.innerHTML);
      }
    </script>

    样式部分,主要调整样式和实现鼠标悬停显示下一级菜单,样式看起来有些拙劣,凑合看吧:

     <style>
      #dimension-tree {
        position: absolute;
        left: 0 !important;
        min-height: 688px;
        border: 1pxsolidrgb (211, 211, 211);
        top: -10px;
        padding: 0;
        width: 100px;
        background: #f5f5f5;
        z-index: 99;
      }
    
      #dimension-tree > li > a {
        font-size: 14px;
        color: rgb(15, 14, 14) !important;
        text-decoration: none;
        cursor: pointer;
        display: block;
        width: 100px;
      }
    
      #dimension-tree > li {
        display: block !important;
        height: 80px;
        line-height: 80px;
      }
    
      .dimensionUl a {
        font-size: 14px;
        color: rgb(15, 14, 14) !important;
        text-decoration: none;
        display: block;
        width: 100px;
        cursor: pointer;
      }
    
      .dimensionLi:hover > .dimensionUl {
        display: block;
      }
    
      .dimensionUl {
        left: 100px;
        top: 0;
        width: 100px;
        height: auto;
        position: absolute;
        background: #f5f5f5;
        list-style: none;
        padding: 0;
        display: none;
      }
    
      .dimensionLi {
        width: 100px;
        height: 50px;
        line-height: 50px;
        text-align: center;
        position: relative;
        border: 1pxsolidrgb (211, 211, 211);
      }
    
      .dimensionLi:hover {
        background: #aaa8a8;
      }
    </style>

    html部分没啥好说的:

     <div>
      <ul id="dimension-tree" #dimensionTree></ul>
    </div>

    完整代码,可以直接复制粘贴

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="Generator" content="demo" />
        <meta name="Author" content="" />
        <meta name="Keywords" content="" />
        <meta name="Description" content="" />
        <title>index</title>
      </head>
      <style>
        #dimension-tree {
          position: absolute;
          left: 0 !important;
          min-height: 688px;
          border: 1pxsolidrgb (211, 211, 211);
          top: -10px;
          padding: 0;
          width: 100px;
          background: #f5f5f5;
          z-index: 99;
        }
    
        #dimension-tree > li > a {
          font-size: 14px;
          color: rgb(15, 14, 14) !important;
          text-decoration: none;
          cursor: pointer;
          display: block;
          width: 100px;
        }
    
        #dimension-tree > li {
          display: block !important;
          height: 80px;
          line-height: 80px;
        }
    
        .dimensionUl a {
          font-size: 14px;
          color: rgb(15, 14, 14) !important;
          text-decoration: none;
          display: block;
          width: 100px;
          cursor: pointer;
        }
    
        .dimensionLi:hover > .dimensionUl {
          display: block;
        }
    
        .dimensionUl {
          left: 100px;
          top: 0;
          width: 100px;
          height: auto;
          position: absolute;
          background: #f5f5f5;
          list-style: none;
          padding: 0;
          display: none;
        }
    
        .dimensionLi {
          width: 100px;
          height: 50px;
          line-height: 50px;
          text-align: center;
          position: relative;
          border: 1pxsolidrgb (211, 211, 211);
        }
    
        .dimensionLi:hover {
          background: #aaa8a8;
        }
      </style>
      <body>
        <div>
          <ul id="dimension-tree" #dimensionTree></ul>
        </div>
        <script>
          //树形结构每个节点结构基本相同
          var data = {
            id: "01",
            value: "维度管理",
            children: [
              {
                id: "11",
                value: "岗位",
                children: []
              },
              {
                id: "12",
                value: "部门",
                children: [
                  {
                    id: "121",
                    value: "信息部",
                    children: []
                  },
                  {
                    id: "122",
                    value: "营运部",
                    children: [
                      {
                        id: "1221",
                        value: "营运条例",
                        children: []
                      },
                      {
                        id: "1222",
                        value: "运营管理",
                        children: []
                      },
                      {
                        id: "1223",
                        value: "运营规范",
                        children: []
                      }
                    ]
                  },
                  {
                    id: "123",
                    value: "质量部",
                    children: []
                  },
                  {
                    id: "124",
                    value: "创新部",
                    children: []
                  },
                  {
                    id: "125",
                    value: "销售部",
                    children: []
                  }
                ]
              },
              {
                id: "13",
                value: "集团",
                children: []
              },
              {
                id: "14",
                value: "分公司",
                children: []
              }
            ]
          };
          //调用方法
          valueSet(data, "dimension-tree");
          //data可替换为动态获取的数据
          //例如
          // private loadDimension(url: string) {
          // return this.httpServiceService.getHttp(url).subscribe(
          // res => {
          // this.valueSet(res, "dimension-tree");
          // },
          // error => {
          // console.log('错误', error);
          // }
          // );
          // }
          function valueSet(dataObject, id) {
            if (dataObject.children.length > 0) {
              for (i in dataObject.children) {
                this.DomEdt(id, dataObject.children[i]);
                this.valueSet(dataObject.children[i], dataObject.children[i].id);
              }
            }
          }
          //DOM操作
          function DomEdt(id, obj) {
            var li = document.createElement("li");
            if (document.getElementById(id)) {
              document.getElementById(id).appendChild(li);
            }
            var a = document.createElement("a");
            a.className = "dimensionA";
            a.textContent = obj.value;
            a.onclick = this.Onclick;
            li.appendChild(a);
            li.className = "dimensionLi";
            var ul = document.createElement("ul");
            li.appendChild(ul);
            ul.id = obj.id;
            ul.className = "dimensionUl";
            // ul.style.cssText = 'display:none';
          }
          //节点绑定事件,可获取节点相关内容
          function Onclick(e) {
            console.log(e.target.innerHTML);
          }
        </script>
      </body>
    </html>
    

     

     

    展开全文
  • 交换机结构,调度算法,毕业生论文,版权有限,仅供参考
  • 原文:http://www.01hr.com/article.jsp?id=9782产品分类,多级的树状结构的论坛,邮件列表等许多地方我们都会遇到这样的问题:如何存储多级结构的数据?在PHP的应用中,提供后台数据存储的通常是关系型数据库,它...
  • 点击“开始”中的“样式”中右下角按钮 点击弹出窗口中最下方第三个按钮 点击“推荐”选项卡,再选择要显示的...逐级建立标题2、标题3等目录结构索引,如图所示。 ...
  • 根据人体不同器官具有不同的弹性这一特点构造了一种基于局部区域约束的图像配准算法。首先抽取骨骼边缘上的点作为标志点,利用软对应匹配算法计算出每一个骨骼与其对应骨骼的刚性变换;然后通过薄板样条插值得出整幅...
  • <p>I have build my user table like this: ... <p>Now I would like to select the 3 blue rows. I have build the following function: ...<pre><code>function display_children($parent, $array = array()) { ...
  • 数据库中如何保存多级结构的数据

    千次阅读 2004-07-11 16:16:00
    产品分类,多级的树状结构的论坛,邮件列表等许多地方我们都会遇到这样的问题:如何存储多级结构的数据? 在PHP的应用中,提供后台数据存储的通常是关系型数据库,它能够保存大量的数据,提供高效的数据检索和更新...
  • <p>I'm new to Golang, and I'm trying to initialize a struct of structs with a list of strings at the bottom. I'd like to be able to access the values inside in a clean and readable way, but it isn...
  • 存储器的多级结构

    千次阅读 2007-04-09 14:28:00
    在一个计算机系统中,对存储器的容量、速度和价格这三个基本性能指标都有一定的要求。存储容量应确保各种应用的需要;存储器速度应尽量与CPU的速度相匹 配并支持I/O操作;存储器的价格应比较合理。...只有采用由多级
  • 解决办法 点击设置,就是那个小齿轮 第二行 Compact Middle Packages 翻译为 紧凑型中间包 取消上面得对号就可以了

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,094
精华内容 1,637
关键字:

多级结构