首页 > 代码库 > 利用 地址引用 进行 快速排树 的简单方法

利用 地址引用 进行 快速排树 的简单方法

小强们难免会和树打交道, 一提到树, 小强们都会想到用递归. 不可否认,我也写了很多年的递归.

但是递归需要大量的循环.

这里,利用地址引用进行快速排树,只需要一次循环.

1,从儿子找父亲

这是我构造的测试数据:

1,0;2,0;3,1;4,3;5,4;6,5;7,4;8,3;9,8;10,9

儿子,父亲;儿子,父亲;儿子,父亲;.....

 

 1      var str = "1,0;2,0;3,1;4,3;5,4;6,5;7,4;8,3;9,8;10,9"; 2             var datas = str.Split(new char[] { ; }) 3                 .Select(s => { 4                     var tmp = s.Split(new char[] { , }); 5                     return new { 6                         ID = tmp[0].ToInt(), 7                         PID = tmp[1].ToInt() 8                     }; 9                 });10 11             var dic = new Dictionary<decimal, Tmp>();12             foreach (var kv in datas) {13                 var tmp = new Tmp() {14                     ID = kv.ID,15                     PID = kv.PID16                 };17 18                 dic.Set(kv.ID, tmp);19 20                 var parent = dic.Get(kv.PID, new Tmp() {21                     ID = kv.PID22                 });23 24                 tmp.Parent = parent;25             }
 1         private class Tmp { 2  3             public int ID { 4                 get; 5                 set; 6             } 7  8             public int PID { 9                 get;10                 set;11             }12             public Tmp Parent {13                 get;14                 set;15             }16         }

除构造测试数据外,只用了一次循环,没有嵌套.

ToInt 和 dic.Set 方法是自定义的扩展方法, 只做辅助,和排树没关系.

 

从根找儿子,没有现成的CS示例,也懒得写, 贴段用于 js treegrid 的代码:

 1     var dealTree = function (tab) { 2         var rows = tab.rows; 3         var row; 4  5         var treeObjs = {}; 6         var tmp = {}; 7  8         for (var i = 0; row = rows[i]; i++) { 9             var id = $(row).attr("data-treegrid-id");10             var pId = $(row).attr("data-treegrid-parentID");11 12             if (id == undefined || pId == undefined)13                 continue;14 15             if (!tmp[pId])16                 tmp[pId] = {};17 18             if (!tmp[id])19                 tmp[id] = { hasChild: false };20 21             tmp[id].pID = pId;22 23             tmp[pId][id] = tmp[id];24             tmp[pId].hasChild = true;25         }26 27         for (var t in tmp) {28             if (tmp[t].pID == undefined) {29                 treeObjs[t] = tmp[t];30             }31         }32 33         return treeObjs;34     }

原理都一样.

写这个东东,主要是从网上找不到适用于直接套在 table 上的 treegrid, 要么是从 json 构造树表,要么是必须先排好行的顺序,用着都很蛋疼.我就需要一个能直接在现有 table 上自动排树的一个表格的功能而以.找了很久都没找到满意的,只能自己动手了:

 

  1 var Treegrid = {};  2 (function (t) {  3   4     var self = this;  5   6     var dealTree = function (tab) {  7         var rows = tab.rows;  8         var row;  9  10         var treeObjs = {}; 11         var tmp = {}; 12  13         for (var i = 0; row = rows[i]; i++) { 14             var id = $(row).attr("data-treegrid-id"); 15             var pId = $(row).attr("data-treegrid-parentID"); 16  17             if (id == undefined || pId == undefined) 18                 continue; 19  20             if (!tmp[pId]) 21                 tmp[pId] = {}; 22  23             if (!tmp[id]) 24                 tmp[id] = { hasChild: false }; 25  26             tmp[id].pID = pId; 27  28             tmp[pId][id] = tmp[id]; 29             tmp[pId].hasChild = true; 30         } 31  32         for (var t in tmp) { 33             if (tmp[t].pID == undefined) { 34                 treeObjs[t] = tmp[t]; 35             } 36         } 37  38         return treeObjs; 39     } 40  41     var getSubIds = function (treeObjs, arr) { 42         for (var t in treeObjs) { 43             if (typeof (treeObjs[t]) != "object") 44                 continue; 45  46             arr.push(t); 47  48             if (treeObjs[t].hasChild) 49                 getSubIds(treeObjs[t], arr); 50         } 51         return arr; 52     } 53  54     var generate = function (treeObjs, tab, tbody, level) { 55         for (var t in treeObjs) { 56             var node = treeObjs[t]; 57  58             if (typeof (node) != "object") 59                 return; 60  61             var row = $(tab).find("tr[data-treegrid-id=" + t + "]"); 62             var td = row.find("td:eq(0)"); 63             var indents = new Array(level).join("<span class=‘treegridIndent‘></span>"); 64  65             var htmls = [indents]; 66  67             if (node.hasChild) { 68                 var subIds = getSubIds(node, new Array()); 69                 htmls.push("<span data-treegrid-subs=‘" + subIds.join(",") + "‘ class=‘glyphicon glyphicon-chevron-down‘></span>") 70             } 71             htmls.push(td.html()); 72  73             td.html(htmls.join("")); 74             tbody.append(row); 75             generate(node, tab, tbody, level + 1); 76         } 77     } 78  79     var init = function (tab) { 80         if ($(tab).attr("data-treegrid-dealed") == true) 81             return; 82  83         var treeObjs = dealTree(tab); 84  85         var tbody = $("<tbody>"); 86  87         generate(treeObjs, tab, tbody, 0); 88         $(tab).append(tbody); 89         $(tab).attr("data-treegrid-dealed", true); 90     } 91  92     $.fn.treegrid = function () { 93         this.each(function () { 94             init(this); 95         }); 96  97         $("span[data-treegrid-subs]").on("click", function () { 98             var subIds = $(this).attr("data-treegrid-subs").split(‘,‘); 99             var explanded = $(this).data("data-treegrid-expandend");100             explanded = explanded == undefined ? true : explanded;101             var id;102             for (var i = 0; id = subIds[i]; i++) {103                 var tr = $("tr[data-treegrid-id=‘" + id + "‘]");104                 tr.toggle(!explanded);105             }106             $(this)107                 .data("data-treegrid-expandend", !explanded)108                 .removeClass("glyphicon-chevron-right").removeClass("glyphicon-chevron-down")109                 .addClass(explanded ? "glyphicon glyphicon-chevron-right" : "glyphicon glyphicon-chevron-down");110         });111     }112 113 })(Treegrid);

最终效果长这样,丑是丑了点,但是简单.

 

谢谢围观.