森林的兩種遍歷方法
前序(先根)遍歷森林
- 找到森林中的所有的根結點。
- 前序遍歷森林中的每個根節點對應的樹。
后序(后根)遍歷森林
- 找到森林中的所有的根結點。
- 后序遍歷森林中的每個根節點對應的樹。
樹的兩種遍歷方法
前序(先根)遍歷樹
- 訪問樹的根結點。
- 找到根節點的所有子節點。
- 前序遍歷每個子節點。
后序(后根)遍歷樹
- 找到根節點的所有子節點。
- 后續序遍歷每個子節點。
- 訪問樹的根結點。
企業應用場景 之 前序遍歷
效果圖
代碼示例
1 /// <reference path="Ext/ext-all-debug-w-comments.js" /> 2 3 function arrayToTree(arr, isRoot, isChild, mapper) { 4 var roots = Ext.Array.filter(arr, isRoot); 5 roots = Ext.Array.map(roots, mapper); 6 7 //遍歷森林 8 Ext.Array.each(roots, function (root) { 9 buildTree(arr, root, isChild, mapper); 10 }); 11 12 return roots; 13 } 14 15 function buildTree(arr, item, isChild, mapper) { 16 //先訪問根節點 17 item.children = getChildren(arr, item, isChild, mapper); 18 19 //后訪問子節點 20 Ext.Array.each(item.children, function (child) { 21 buildTree(arr, child, isChild, mapper); 22 }); 23 } 24 25 function getChildren(arr, parent, isChild, mapper) { 26 var children = Ext.Array.filter(arr, function (item) { 27 return isChild(parent, item); 28 }); 29 30 return Ext.Array.map(children, mapper); 31 } 32 33 function arrayToTreeString(arr, isRoot, isChild) { 34 var roots = Ext.Array.filter(arr, isRoot); 35 36 var treeString = ''; 37 38 //遍歷森林 39 Ext.Array.each(roots, function (root) { 40 treeString += buildTreeString(arr, root, isChild, 0); 41 }); 42 43 return treeString; 44 } 45 46 function buildTreeString(arr, item, isChild, level) { 47 var treeString = ''; 48 49 //先訪問根節點 50 treeString += Ext.String.repeat('-', (level + 1) * 5) + '| ' + item.title + '<br/><br/>'; 51 52 //后訪問子節點 53 var children = getChildren(arr, item, isChild, function (child) { 54 return child; 55 }); 56 Ext.Array.each(children, function (child) { 57 treeString += buildTreeString(arr, child, isChild, level + 1); 58 }); 59 60 return treeString; 61 } 62 63 Ext.onReady(function () { 64 var arr = [ 65 { id: '100', title: '編輯', parent: '000' }, 66 { id: '110', title: '復制', parent: '100' }, 67 { id: '120', title: '查找與替換', parent: '100' }, 68 { id: '121', title: '快速查找', parent: '120' }, 69 { id: '122', title: '快速替換', parent: '120' }, 70 { id: '130', title: '撤銷', parent: '100' }, 71 { id: '140', title: '重做', parent: '100' }, 72 ]; 73 74 var tree = arrayToTree(arr, function (item) { 75 return item.parent === '000'; 76 }, function (parent, item) { 77 return item.parent === parent.id; 78 }, function (item) { 79 return { id: item.id, text: item.title, parent: item.parent, expanded: true }; 80 }); 81 82 var treeString = arrayToTreeString(arr, function (item) { 83 return item.parent === '000'; 84 }, function (parent, item) { 85 return item.parent === parent.id; 86 }); 87 88 Ext.create('Ext.container.Viewport', { 89 layout: { 90 type: 'vbox', 91 align: 'stretch' 92 }, 93 padding: 10, 94 items: [{ 95 xtype: 'treepanel', 96 title: '表格到樹', 97 frame: true, 98 flex: 1, 99 root: { 100 text: '菜單', 101 expanded: true, 102 children: tree 103 } 104 }, { 105 xtype: 'panel', 106 title: '表格到下拉框', 107 frame: true, 108 flex: 1, 109 html: treeString 110 }] 111 }); 112 });
備注
面對大數據量的森林,上面的遍歷算法有很大的缺陷(速度太慢),因此要從數據存儲結構上下工夫,進而優化遍歷算法。