英文:
Recreating LinkedList of pointers from list of pointers
问题
我有一个随机“指针”列表。
- “A,B,C,D,E,F”
它们属于 N 个不同的链表
- “A->C->D”,“B->E”,“F”
我只能从指针中获取“子节点”知道“父节点”,但反过来不行。
将它们排序到各自的链表中的当前实现如下。
如果可以的话,我会感谢您对优化下面代码的一些建议,或者如果我的方法是错误的。
for (Pointer i: listOfPointers) {
if (!i.hasParent())
// 没有父节点,是根节点
rootNodes.add(i.getId());
else {
// 父节点 -> 子节点
parentChild.put(i.getParent().getId(),i.getId());
}
}
// 遍历头部/根节点
for (String i : rootNodes) {
LinkedList<String> templist = new LinkedList<>();
LinkedList<Map<String,String>> temp = new LinkedList<>();
String tempnow = i;
// 构建我们的链表,从头开始获取子节点,直到没有剩余节点
do{
if (templist.size() == 0)
System.out.println("父节点 - " + tempnow);
else
System.out.println("子节点 - " + tempnow);
templist.add(tempnow);
if (parentChild.containsKey(tempnow))
tempnow = parentChild.get(tempnow);
else
break;
}while(true);
linkedListHashMap.put(i, templist);
}
英文:
I have a list of random "pointers"
- "A,B,C,D,E,F"
They belong into N different linked lists
- "A->C->D", "B->E", "F"
The only information I can get from the pointers is that the "child" knows the "parent" but not the other way around.
My current implementation to sort them into their own respective linked list is as below.
Would appreciate if i can get some pointers on optimizing the code below or if my approach to it is wrong.
for (Pointer i: listOfPointers) {
if (!i.hasParent())
// no parent, its a root node
rootNodes.add(i.getId());
else {
// parent -> child
parentChild.put(i.getParent().getId(),i.getId());
}
}
// iterate through the head/roots
for (String i : rootNodes) {
LinkedList<String> templist = new LinkedList<>();
LinkedList<Map<String,String>> temp = new LinkedList<>();
String tempnow = i;
//construct our linked list, start by the head and getting the child until we have nothing left
do{
if (templist.size() == 0)
System.out.println("Parent - " + tempnow);
else
System.out.println("Child - " + tempnow);
templist.add(tempnow);
if (parentChild.containsKey(tempnow))
tempnow = parentChild.get(tempnow);
else
break;
}while(true);
linkedListHashMap.put(i, templist);
}
答案1
得分: 1
以下是您要翻译的内容:
我将创建一个Map
,将每个Pointer
映射到其父节点(实际上是边的Map
),除了需要单独存储的根节点。之后,您可以通过反复遍历图形来重建List
,直到不再找到映射。
public Collection<List<Pointer>> group(Collection<Pointer> pointers) {
if(pointers.isEmpty()) {
return Collections.emptyList();
}
List<Pointer> roots = new ArrayList<>();
Map<Pointer, Pointer> parents = new HashMap<>(pointers.size());
for(Pointer pointer : pointers) {
if(pointer.hasParent()) {
parents.put(pointer.getParent(), pointer);
} else {
roots.add(pointer);
}
}
List<List<Pointer>> results = new ArrayList<>(roots.size());
for(Pointer root : roots) {
List<Pointer> list = new LinkedList<>();
list.add(root);
Pointer current = parents.get(root);
while(current != null) {
list.add(current);
current = parents.get(current);
}
results.add(list);
}
return results;
}
对于您提供的输入:
Pointer a = new Pointer("A");
Pointer c = new Pointer("C", a);
Pointer d = a Pointer("D", c);
Pointer b = new Pointer("B");
Pointer e = new Pointer("E", b);
Pointer f = new Pointer("F");
Collection<Pointer> pointers = Arrays.asList(a, b, c, d, e, f);
Collection<List<Pointer>> grouped = group(pointers);
// 结果: A -> C-> D ; B -> E ; F
英文:
I would create a Map
which maps each Pointer
by its parent (effectively a Map
of edges), except the root nodes which need to be stored separately. Afterwards, you can reconstruct the List
by repeatetly traversing the graph until no further mapping is found.
public Collection<List<Pointer>> group(Collection<Pointer> pointers) {
if(pointers.isEmpty()) {
return Collections.emptyList();
}
List<Pointer> roots = new ArrayList<>();
Map<Pointer, Pointer> parents = new HashMap<>(pointers.size());
for(Pointer pointer : pointers) {
if(pointer.hasParent()) {
parents.put(pointer.getParent(), pointer);
} else {
roots.add(pointer);
}
}
List<List<Pointer>> results = new ArrayList<>(roots.size());
for(Pointer root : roots) {
List<Pointer> list = new LinkedList<>();
list.add(root);
Pointer current = parents.get(root);
while(current != null) {
list.add(current);
current = parents.get(current);
}
results.add(list);
}
return results;
}
For you given input:
Pointer a = new Pointer("A");
Pointer c = new Pointer("C", a);
Pointer d = new Pointer("D", c);
Pointer b = new Pointer("B");
Pointer e = new Pointer("E", b);
Pointer f = new Pointer("F");
Collection<Pointer> pointers = Arrays.asList(a, b, c, d, e, f);
Collection<List<Pointer>> grouped = group(pointers);
// result: A -> C-> D ; B -> E ; F
答案2
得分: 0
以下是您提供的内容的翻译:
虽然在原始列表的基础上构建其他数据结构的直接解决方案很简单,但我认为找到一种需要恒定数量的附加内存的解决方案会很有趣,就像这个解决方案一样:
boolean sorted = false;
while (!sorted) {
sorted = true;
for (Element element : elements) {
Element parent = element.parent;
if (parent != null) {
Element grandParent = parent.parent;
if (grandParent != null && parent.value > grandParent.value) {
element.parent = grandParent;
parent.parent = grandParent.parent;
grandParent.parent = parent;
sorted = false;
}
}
}
}
// 现在所有列表的尾部都已排序,只有头部(第一个元素)可能被放错位置
for (Element element : elements) {
Element parent = element.parent;
Element child = null;
while (parent != null && element.value > parent.value) {
if (child != null)
child.parent = parent;
element.parent = parent.parent;
parent.parent = element;
child = parent;
parent = element.parent;
}
}
思路是,当所有列表都排序好时,每个元素可能不大于其父元素。因此,如果我们看到 A->B->C->...
且 B > C
,那么我们会将这个片段重新排列为 A->C->B->...
。我们会一直进行这样的操作,直到没有这样的片段需要重新排列为止,这意味着所有列表的尾部都已排序,只有头部(第一个元素)可能被放错位置。
现在,我们寻找类似 A->B->...
的片段,其中 A > B
。由于只有头部可能被放错位置,而且明显 A
被放错了,那么 A
就是一个头部,即 A
没有子元素。因此,我们可以从 A
开始迭代列表,找到 A
应该放置在列表的哪个位置,并将 A
移动到那个位置,无需更新 A
的子元素,因为已保证 A
没有子元素。
以下是对随机数据运行此算法的示例:
原始数据:
(请注意,由于排版限制,我无法在此处显示原始数据)
第一轮后:
(请注意,由于排版限制,我无法在此处显示第一轮后的数据)
第二轮后:
(请注意,由于排版限制,我无法在此处显示第二轮后的数据)
如果您有任何进一步的问题或需要其他帮助,请随时问我。
英文:
While there are straightforward solutions that build additional data structures on the top of original list, I think it would be interesting to find a solution that requires constant amount of additional memory, like this one:
<!-- language: lang-java -->
boolean sorted = false;
while (!sorted) {
sorted = true;
for (Element element: elements) {
Element parent = element.parent;
if (parent != null) {
Element grandParent = parent.parent;
if (grandParent != null && parent.value > grandParent.value) {
element.parent = grandParent;
parent.parent = grandParent.parent;
grandParent.parent = parent;
sorted = false;
}
}
}
}
// Now the tails of all lists are sorted, only the heads
// (first elements) may be misplaced
for (Element element : elements) {
Element parent = element.parent;
Element child = null;
while (parent != null && element.value > parent.value) {
if (child != null)
child.parent = parent;
element.parent = parent.parent;
parent.parent = element;
child = parent;
parent = element.parent;
}
}
The idea is that when all lists are sorted, each element may not be greater than its parent. So if we see A->B->C->...
and B > C
, then we rearrange this fragment as A->C->B->...
. We do this until there are no such fragments to rearrange, which means that the tails of all lists are sorted and only the heads (first elements) may be misplaced.
Now we look for fragments looking like A->B->...
where A > B
. As only the heads may be misplaced, and A
is obviously misplaced, then A
is a head, i.e. there are no children of A. So we may iterate through the list starting at A
, find where in this list A
should be placed, and move A
there, without necessity to update the children of A
as A
guaranteed to have no children.
Here is an example run on random data:
Original:
78->77->2->39->67->78->98->
86->30->71->90->86->97->98->30->88->31->67->19->36->5->57->16->
7->16->19->12->74->98->55->60->38->25->2->37->45->92->3->52->24->43->41->84->95->73->77->19->91->15->29->60->
17->94->25->
34->80->
51->
68->23->1->89->5->17->67->35->97->26->57->38->
89->84->
58->
8->5->87->43->8->
72->60->
41->49->28->92->84->
41->33->15->8->55->40->16->58->13->86->35->16->77->71->
53->13->
After the first loop:
78->2->39->67->77->78->98->
86->5->16->19->30->30->31->36->57->67->71->86->88->90->97->98->
7->2->3->12->15->16->19->19->24->25->29->37->38->41->43->45->52->55->60->60->73->74->77->84->91->92->95->98->
17->25->94->
34->80->
51->
68->1->5->17->23->26->35->38->57->67->89->97->
89->84->
58->
8->5->8->43->87->
72->60->
41->28->49->84->92->
41->8->13->15->16->16->33->35->40->55->58->71->77->86->
53->13->
After the second loop:
84->89->
5->8->8->43->87->
2->39->67->77->78->78->98->
13->53->
17->25->94->
28->41->49->84->92->
8->13->15->16->16->33->35->40->41->55->58->71->77->86->
60->72->
34->80->
51->
5->16->19->30->30->31->36->57->67->71->86->86->88->90->97->98->
58->
1->5->17->23->26->35->38->57->67->68->89->97->
2->3->7->12->15->16->19->19->24->25->29->37->38->41->43->45->52->55->60->60->73->74->77->84->91->92->95->98->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论