需要更新一批数据,需要按照父子关系依次更新,前提是如果有父节点一定要先更新父节点。
这个算法感觉有些麻烦,不知是否有更好的方法
示例数据:
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<int, int>(1, -1),
new KeyValuePair<int, int>(5, -1),
new KeyValuePair<int, int>(323, 32),
new KeyValuePair<int, int>(555, 55),
new KeyValuePair<int, int>(55, 5),
new KeyValuePair<int, int>(87, 8),
new KeyValuePair<int, int>(633, 63),
new KeyValuePair<int, int>(63, 6),
new KeyValuePair<int, int>(2, -1),
new KeyValuePair<int, int>(3232, 323)
};
var testList = GetSortedList(list);
{
new KeyValuePair<int, int>(1, -1),
new KeyValuePair<int, int>(5, -1),
new KeyValuePair<int, int>(323, 32),
new KeyValuePair<int, int>(555, 55),
new KeyValuePair<int, int>(55, 5),
new KeyValuePair<int, int>(87, 8),
new KeyValuePair<int, int>(633, 63),
new KeyValuePair<int, int>(63, 6),
new KeyValuePair<int, int>(2, -1),
new KeyValuePair<int, int>(3232, 323)
};
var testList = GetSortedList(list);
排序
private static List<KeyValuePair<int, int>> GetSortedList(IEnumerable<KeyValuePair<int, int>> list)
{
var tempList = new List<KeyValuePair<int, int>>();
tempList.AddRange(list);
var result = new List<KeyValuePair<int, int>>();
foreach (var keyValuePair in list)
{
if (!tempList.Contains(keyValuePair)) continue;
var parentList = new List<KeyValuePair<int, int>>();
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<int, int>>();
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;
}
{
var tempList = new List<KeyValuePair<int, int>>();
tempList.AddRange(list);
var result = new List<KeyValuePair<int, int>>();
foreach (var keyValuePair in list)
{
if (!tempList.Contains(keyValuePair)) continue;
var parentList = new List<KeyValuePair<int, int>>();
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<int, int>>();
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<int, int>> newlist,
IEnumerable<KeyValuePair<int, int>> 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<int, int>> newlist,
IEnumerable<KeyValuePair<int, int>> 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);
}
}
IEnumerable<KeyValuePair<int, int>> 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<int, int>> newlist,
IEnumerable<KeyValuePair<int, int>> 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<int, int>(1, -1),
new KeyValuePair<int, int>(5, -1),
new KeyValuePair<int, int>(55, 5),
new KeyValuePair<int, int>(17, 1),
new KeyValuePair<int, int>(558, 55),
new KeyValuePair<int, int>(174, 17),
new KeyValuePair<int, int>(2, -1),
};
var result= new List<KeyValuePair<int, int>>();
BuildParentChildList(-1, ref result, list);
{
new KeyValuePair<int, int>(1, -1),
new KeyValuePair<int, int>(5, -1),
new KeyValuePair<int, int>(55, 5),
new KeyValuePair<int, int>(17, 1),
new KeyValuePair<int, int>(558, 55),
new KeyValuePair<int, int>(174, 17),
new KeyValuePair<int, int>(2, -1),
};
var result= new List<KeyValuePair<int, int>>();
BuildParentChildList(-1, ref result, list);
private static void BuildParentChildList(int parentId,ref List<KeyValuePair<int, int>> targetList ,
List<KeyValuePair<int, int>> 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);
}
}
List<KeyValuePair<int, int>> 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);
}
}