Program,Life,Society.....

导航

统计

公告

父子关系排序,无确定根节点

需要更新一批数据,需要按照父子关系依次更新,前提是如果有父节点一定要先更新父节点。

这个算法感觉有些麻烦,不知是否有更好的方法

示例数据:

ID,ParentID
(1, -1),(5, -1),(323, 32), (555, 55),(55, 5),(87, 8),(633, 63),(63, 6),(2, -1),(3232, 323)

排序后的结果
  1,5,55,555,323,3232,87,63,633,2

 

var list = new List<KeyValuePair<int,int>>
               {
                   
new KeyValuePair<intint>(1-1),
                   
new KeyValuePair<intint>(5-1),
                   
new KeyValuePair<intint>(32332),
                   
new KeyValuePair<intint>(55555),
                   
new KeyValuePair<intint>(555),
                   
new KeyValuePair<intint>(878),
                   
new KeyValuePair<intint>(63363),
                   
new KeyValuePair<intint>(636),
                   
new KeyValuePair<intint>(2-1),
                   
new KeyValuePair<intint>(3232323)
               };
var testList 
= GetSortedList(list);

 排序

        private static List<KeyValuePair<intint>> GetSortedList(IEnumerable<KeyValuePair<intint>> list)
        {
            var tempList 
= new List<KeyValuePair<intint>>();
            tempList.AddRange(list);
            var result 
= new List<KeyValuePair<intint>>();
            
foreach (var keyValuePair in list)
            {
                
if (!tempList.Contains(keyValuePair)) continue;
                var parentList 
= new List<KeyValuePair<intint>>();
                BuildParent(keyValuePair.Value, 
ref parentList, list);
                
for (var i = parentList.Count - 1; i >= 0; i--)
                {
                    
if (!tempList.Contains(parentList[i])) continue;
                    result.Add(parentList[i]);
                    tempList.Remove(parentList[i]);
                }
                result.Add(keyValuePair);
                tempList.Remove(keyValuePair);

                var childList 
= new List<KeyValuePair<intint>>();
                BuildChild(keyValuePair.Key, 
ref childList, list);
                
for (var i = 0; i < childList.Count; i++)
                {
                    
if (!tempList.Contains(childList[i])) continue;
                    result.Add(childList[i]);
                    tempList.Remove(childList[i]);
                }
            }
            
return result;
        }

构建孩子列表和父亲列表

        private static void BuildChild(int parentId, ref List<KeyValuePair<intint>> newlist,
                                                      IEnumerable
<KeyValuePair<intint>> list)
        {
            var children 
= from keyValuePair in list
                           
where keyValuePair.Value == parentId
                           select keyValuePair;
            
foreach (var child in children)
            {
                newlist.Add(child);
                BuildChild(child.Key, 
ref newlist, list);
            }
        }
        
private static void BuildParent(int childId, ref List<KeyValuePair<intint>> newlist,
                                                      IEnumerable
<KeyValuePair<intint>> list)
        {
            
           var parents 
= from keyValuePair in list
                                  
where keyValuePair.Key == childId
                                   select keyValuePair;
             
foreach (var parent in parents)
                {
                 newlist.Add(parent);
                 BuildParent(parent.Value, 
ref newlist, list);  
                }
 
          
        }

 如果有固定的根节点就好排序多了

            var list = new List<KeyValuePair<int,int>>
                           {
                               
new KeyValuePair<intint>(1-1),
                               
new KeyValuePair<intint>(5-1),
                      
        new KeyValuePair<intint>(555),
                               
new KeyValuePair<intint>(17, 1),
                               
new KeyValuePair<intint>(558, 55),
                               
new KeyValuePair<intint>(174, 17),
                               
new KeyValuePair<intint>(2-1),
                          
                           };
            var result
= new List<KeyValuePair<intint>>();
            BuildParentChildList(
-1ref result, list);

     private static  void BuildParentChildList(int parentId,ref List<KeyValuePair<intint>> targetList ,
                                                           List
<KeyValuePair<intint>> sourceList)
        {
            var dic 
= from source in sourceList
                           
where  source.Key== parentId
                           select source;
            
foreach (var source in dic)
            {
                var childParentId 
= source.Key;
                targetList.Add(source);
                BuildParentChildList(childParentId, 
ref targetList, sourceList);
            }
        }

posted on 2010-03-15 10:51 rippleyong 阅读(...) 评论(...) 编辑 收藏