现在的位置: 首页 > 综合 > 正文

谦虚的向大家问个技术问题,树型结构的排序问题

2013年10月03日 ⁄ 综合 ⁄ 共 5909字 ⁄ 字号 评论关闭
文章目录

1:若是一个系统管理员,对数据进行了排序(微软的树形控件、遍历节点不太友善),那这个排序结果怎么保存?怎么产生排序算法?假设是一个无限的树形结构?读取数据时,如何读取才能按树形的结构可以在列表里显示出来?排序的算法写起来是否很简单、易懂?

 

2:若一个管理员只是一个省级的管理员,他只能加载一个省的数据,然后对这个省的数据进行了排序操作,可能有新增、删除、修改等等操作,那排序的结果会不会影响整体的排序算法?分级管理员排序后的数据是否能保证整体上是正确的?

 

这2个问题困扰了我蛮久了,当然那种思路不是很严谨的,我也会,就是想知道一下,是否有很牛B的思路,可以把这个问题解决得非常合理,让人感觉心服口服的做法不知道是否有?参考效果图如下。

 

想达到的目的就是,读取数据库中的数据时,正好是按这个树形结构的排序顺序读取出来的,树节点的先后顺序与数据表中的顺序是保持一致的目的。

将权限管理、工作流管理做到我能力的极致,一个人只能做好那么很少的几件事情。

posted on 2010-04-18 12:15 不仅仅是通用权限设计 阅读(1893) 评论(48) 编辑 收藏

评论

#1楼  回复 引用 查看    沙发,谁有最新的比较全的全国省市县数据库,共享一下。ccycc@msn.com

2010-04-18 12:35 | ccycc      

#2楼  回复 引用 查看   

排序什么?

2010-04-18 12:40 | 诺贝尔      

#3楼  回复 引用 查看   

首页成CSDN了

2010-04-18 12:40 | net1234      

#4楼  回复 引用 查看   

每个人可能观注的要点不一样,所以排序的结果顺序状态可以存本地。在本地存储时,不需要把排序的结果存起来,可以存一下排序的方式,存的内容包含节点标识及子节点排序方式,在树节点展开时来完成该节点下子节点的排序和加载。
这样的方式和树的层次深度无关,和增、删、改节点操作无关,局部的更改也不会影响整体,因为根本就不存在整体排序。选择一个节点时,右侧的列表直接按对应节点的排序方式加载数据即可。

2010-04-18 12:42 | heros      

#5楼[楼主]  回复 引用 查看   

你也别总想着打击我,也未必能回答出我的问题,也未必有能力做得比较理想的,你就别装了吧,一个心态好的人不会发你这样的狗屁留言的。

引用

net1234:首页成CSDN了

#6楼[楼主]  回复 引用 查看   

@诺贝尔
把各个组织机构的排序顺序合理的保存起来,就是读取出来的时候,正好是这个树形结构的排序顺序的先后顺序读出来的。

#7楼  回复 引用 查看   

单独把排序的数据存起来,显示的时候按照用户上次保存的那个顺序重新排序就可以了

2010-04-18 12:49 | omeweb      

#8楼[楼主]  回复 引用 查看   

@omeweb

我如何保存排序顺序呢?

#9楼  回复 引用 查看   

@吉日嘎拉 不仅权限设计

按照编号存储啊,比如某用户要把 上城区330102排在市辖区330101的前面,那存储为 330102,330101,显示的时候按照这个顺序,重新排一下再输出就可以了

2010-04-18 12:55 | omeweb      

#10楼  回复 引用 查看   

序列化不就能存了嘛

2010-04-18 12:56 | heros      

#11楼  回复 引用 查看   

用深度来对树形结构进行分节,数据表格如下:
--TreeSchema
NodeID Depth Parent
情况1:如果相同的深度上排序方案是一样的,可以增加一个表
--NodeSortHandler
Depth Handler
实现:UI->根据权限获取最浅深度节点->根据该深度排序->显示...(其他深度依次类推)
情况2:如果是自定义排序后保存,对TreeSchema增加一个列,
--TreeSchema
NodeID Depth Parent DepthIndex
实现:UI->根据权限获取最浅深度节点->根据DepthIndex排序->显示...

2010-04-18 12:58 | 螃蟹往前冲      

#12楼  回复 引用 查看   

你这个又不可能出现一个子树在其他节点下出现的情况,那就每个节点都记录一下他在父节点下的第几个就可以了啊。
比如杭州下:市辖区为1,上层区为2.
浙江为省下杭州为1....

2010-04-18 13:03 | liy-apple      

#13楼  回复 引用 查看   

你问个屁的问题啊,回家问你爹啊,别人有义务教你吗,儿子,
你的东西不是卖钱的,

2010-04-18 13:09 | net1234      

#14楼  回复 引用 查看   


引用

omeweb:
@吉日嘎拉 不仅权限设计

按照编号存储啊,比如某用户要把 上城区330102排在市辖区330101的前面,那存储为 330102,330101,显示的时候按照这个顺序,重新排一下再输出就可以了

我还是没搞太明白,瞎说几句吧!

如我来设计,就将编号拆分成,省、市、区三个字段,每个字段都可以单独设置升序或降序。

2010-04-18 13:14 | 卡通一下      

#15楼  回复 引用 查看   

SQL Server 2008里面有个新的data type叫做hierarchyid,可以用它来界定一个record在树里面的位置,而且这个data type还可以添加索引来控制records的顺序,可选择按照branch或者level来排序。
具体内容可见msdn,解释得很详细。
http://msdn.microsoft.com/en-us/library/bb677290.aspx

2010-04-18 13:16 | Henry Liang      

#16楼  回复 引用 查看   

首先问问题的逻辑就有问题,不知道怎么问,让别人怎么回答。
如果问的好,自己都自己怎么解决了,解决问题,首先要自己思考,简直无语了

2010-04-18 13:19 | 雷米      

#17楼  回复 引用 查看   

树形数据结构有两种存储方式:
1是以编码确定层级,如0102为01节点的下级
2另有层级关系表,ERP系统中的BOM表即是层级数据结构典型的例子。
数形结构的排序比较简单,带出某节点的子节点时指定某字段为排序字段即可。在第一种方式存储时,如:select * from t1 where code like "01__" order by xxx. 其中xxx可为编码字段code,亦可为其他排序字段。

2010-04-18 13:30 | 沧海月明      

#18楼  回复 引用 查看   

假设是一个无限的树形结构?那个我不会,一般一个树有个10级就把人弄晕了。
但是如果假设不是无限级别的。
可以考虑一下专门用一个字段来排序,定个规则,比如第一级下节点不超过100个,用00-99,第二级不超过1000个,使用000-999,依此类推,得到节点的排序号。
进行维护的时候把整个表的排序字段维护一下就可以了。
如果是分权限了,则根节点排序号不会变了,不会影响到别的了。

2010-04-18 13:44 | firesword      

#19楼  回复 引用 查看   


引用

卡通一下:

引用

omeweb:
@吉日嘎拉 不仅权限设计

按照编号存储啊,比如某用户要把 上城区330102排在市辖区330101的前面,那存储为 330102,330101,显示的时候按照这个顺序,重新排一下再输出就可以了

我还是没搞太明白,瞎说几句吧!

如我来设计,就将编号拆分成,省、市、区三个字段,每个字段都可以单独设置升序或降序。

编号|级别
43|2
44|2
4310|4
4305|4
4420|4
4410|4
431005|6
431008|6

显示每级别的时候就从该表里找到顺序数据,排序一下就可以了

2010-04-18 13:46 | omeweb      

#20楼  回复 引用 查看   

增加一个字段,保存好排序的序号。

省级代理可以排序其管理的省级,市级代理排序其市级,区级代理排序其区级,这是个一个权限的问题。

当,一个级别的代理多于一人,那么就不是一个字段能解决的,必须要根据每个人设置一个字段,大家的排序偏好不同嘛。

增删改,无限还是有限,都和排序没什么关系。

排序主要还是UI的问题,可以独立于其他业务。

2010-04-18 14:25 | 诺贝尔      

#21楼  回复 引用 查看   

不知道我这种设计对不对:
关于这个排序我用到的表结构如下:
三个列:id name belongID order
id:自动编号
name: 项目名称例如省市区等等名称
belongID:父节点的ID
order: 排序顺序 注意:我考虑到你的迷惑地方,就是排序后会不会影响到
整体的排序问题 其实有这样一个事实:他们排序范围是一定的 他们必须在相同区域内 也就是他们有相同的belongID 用户排完序后序号存在order
列类里面
因为表结构简单 所以具备无限的扩充性 也就是你说的无限级树级结构
当然这个复杂在sql算法上 最近正在研究这方面的内容 具体算法还没写
写完了 再贴上
不知道 我说的是不是你所问的

2010-04-18 14:36 | chenxumi      

#22楼  回复 引用 查看   

好家伙,几位搞的真复杂。复杂了就说明有问题了。

2010-04-18 14:42 | heros      

#23楼  回复 引用 查看   

吉日我原来挺佩服你的,现在感觉失望极了.

2010-04-18 14:59 | 根号贰      

#24楼  回复 引用 查看   

用深度优先遍历树

2010-04-18 15:59 | 竹迹      

#25楼  回复 引用 查看   


引用

沧海月明:
树形数据结构有两种存储方式:
1是以编码确定层级,如0102为01节点的下级
2另有层级关系表,ERP系统中的BOM表即是层级数据结构典型的例子。
数形结构的排序比较简单,带出某节点的子节点时指定某字段为排序字段即可。在第一种方式存储时,如:select * from t1 where code like "01__" order by xxx. 其中xxx可为编码字段code,亦可为其他排序字段。

这位兄弟说的比较好,我目前是按第一种方式处理。另:编码字段可做为私有成员,由系统自动维护。这样还可以按照编码的长度知道节点的深度,在下拉列表中显示时,可以根据深度缩进。
吉日兄在技术方面确实该谦虚点。

2010-04-18 16:31 | 王庭安      

#26楼  回复 引用 查看   

用序列化,为每一个用户保存一个profile文件(可在数据库外,也可写入数据库,也可以用db4o来管理),然后将排序逻辑IComparer<T>直接序列化进去,然后根据每一次调用方实例的HashCode或其它标识来进行处理。这个的问题是数据会不断膨胀,可以记录每一个排序逻辑的最后访问时间,访问次数,以及是否出现异常,定期删除过久不访问的及出现异常的就可以了。这样就可以维护系统的任何排序逻辑了,比如,搜索结果的排序,都可以一并维护,也不会增加啥代码量,并且对重构友好。
树形控件遍历不友善,自己进行扩展即可。

2010-04-18 16:45 | xiaotie      

#27楼  回复 引用 查看   

我是这么处理排序的,不知道是不是楼主想要的答案。
表结构
Id ParentId Position

ParentId用来支持树形结构
Position是排序字段

取数据,把parentid=null order by position 然后把这数据递归就是一个树结构。

新增一个节点:这个节点一定会放在任意父结点的最后一个,所以Position取最大值。

删除一个节点:因为不影响排序的结构,所以不用处理。

移动节点:把position介于drag.position与drop.position之间的元素进行调整前移或者后移,调整drag与drop就可以了。

主要关注点:只要保证任一结点下的子结点position是递增就可以了,是1,2,3还是1,3,5不会影响结果。

2010-04-18 16:46 | a-peng      

#28楼  回复 引用 查看   

@吉日嘎拉 不仅权限设计
你的回复已经表现出了你的心态

2010-04-18 17:20 | tandly      

#29楼  回复 引用 查看   

号称有十年软件开发的牛B级人。。

2010-04-18 17:53 | 不若相忘于江湖      

#30楼  回复 引用 查看   

1 想达到的目的就是,读取数据库中的数据时,正好是按这个树形结构的排序顺序读取出来的,树节点的先后顺序与数据表中的顺序是保持一致的目的。

老实讲。你的技术不咋的。 这种可以使用流水号来解决。

具体使用方法上面已经回答。。。

2 若是一个系统管理员,对数据进行了排序(微软的树形控件、遍历节点不太友善),那这个排序结果怎么保存?怎么产生排序算法?假设是一个无限的树形结构?读取数据时,如何读取才能按树形的结构可以在列表里显示出来?排序的算法写起来是否很简单、易懂?

那这个排序结果怎么保存?
答: 很多种。序列化到本地。
怎么产生排序算法?
答: 不解啥意思。
读取数据时,如何读取才能按树形的结构可以在列表里显示出来?排序的算法写起来是否很简单、易懂?
答: 流水号解决。 再使用Like模糊查询。

2010-04-18 17:58 | 不若相忘于江湖      

#31楼  回复 引用 查看   

@liy-apple
我的理解也是如此。

2010-04-18 18:50 | 在别处      

#32楼  回复 引用 查看   

这个应用可以很简单,也可以很复杂。我想吉日的意思是不满足现有程序的效率,对于数据量稍大一点点的应用来说,我还没见过哪个树控件能很好地解决效率的问题。事实上,对于类似应用,我们应该想得到,每次用户在维护这棵树的时候,他需要更改的数据量都很小,可能仅仅是针对某个特定节点的下级节点去维护,而不是一次完成整棵树的维护的理想状态(不是还有数据初始化么,呵呵)。所以,不要太理想化,只需能够满足基本应用,这个问题就很好处理……

2010-04-18 19:45 | 蜡人张      

#33楼  回复 引用 查看   

树形控件解决效率的最好办法就是动态加载,首先只加载第一层级,点一下加载一次。别一下递归绑定。

2010-04-18 19:55 | Robin Zhang      

#34楼  回复 引用 查看   

楼主

抱歉!评论已关闭.