Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从指针列表重新创建指针的LinkedList_Java_Pointers - Fatal编程技术网

Java 从指针列表重新创建指针的LinkedList

Java 从指针列表重新创建指针的LinkedList,java,pointers,Java,Pointers,我有一个随机的“指针”列表 “A、B、C、D、E、F” 它们属于N个不同的链表 “A->C->D”,“B->E”,“F” 我能从指针中得到的唯一信息是“子”知道“父”,而不是相反 我当前将它们分类到各自的链表中的实现如下所示 如果我能得到一些关于优化下面代码的建议,或者我的方法是错误的,我将不胜感激 for(指针i:指针列表){ 如果(!i.hasParent()) //没有父节点,它是根节点 add(i.getId()); 否则{ //父->子 parentChild.put(i.ge

我有一个随机的“指针”列表

  • “A、B、C、D、E、F”
它们属于N个不同的链表

  • “A->C->D”,“B->E”,“F”
我能从指针中得到的唯一信息是“子”知道“父”,而不是相反

我当前将它们分类到各自的链表中的实现如下所示

如果我能得到一些关于优化下面代码的建议,或者我的方法是错误的,我将不胜感激

for(指针i:指针列表){
如果(!i.hasParent())
//没有父节点,它是根节点
add(i.getId());
否则{
//父->子
parentChild.put(i.getParent().getId(),i.getId());
}
}
//遍历头/根
for(字符串i:根节点){
LinkedList templist=新建LinkedList();
LinkedList temp=新建LinkedList();
字符串tempnow=i;
//构建我们的链表,从头部开始,得到孩子,直到我们一无所有
做{
if(templast.size()==0)
System.out.println(“父项-”+tempnow);
其他的
System.out.println(“Child-”+tempnow);
圣堂武士。加上(现在);
if(parentChild.containsKey(tempnow))
tempnow=parentChild.get(tempnow);
其他的
打破
}虽然(正确);
linkedListHashMap.put(i,圣殿骑士);
}

虽然有一些简单的解决方案可以在原始列表的顶部构建额外的数据结构,但我认为找到一个需要恒定额外内存量的解决方案会很有趣,比如:

boolean排序=false;
而(!排序){
排序=真;
for(元素:元素){
元素父元素=Element.parent;
如果(父项!=null){
元素祖父母=parent.parent;
if(祖父母!=null&&parent.value>grandParent.value){
element.parent=祖父母;
parent.parent=祖父母.parent;
祖父母。父母=父母;
排序=假;
}
}
}
}
//现在所有列表的尾部都已排序,只有头部
//(第一个元素)可能放错了位置
for(元素:元素){
元素父元素=Element.parent;
元素child=null;
while(parent!=null&&element.value>parent.value){
if(child!=null)
child.parent=parent;
element.parent=parent.parent;
parent.parent=元素;
孩子=父母;
parent=element.parent;
}
}
其思想是,当所有列表都被排序时,每个元素可能不会大于其父元素。因此,如果我们看到
A->B->C->……
B>C
,那么我们将这个片段重新排列为
A->C->B->……
。我们这样做直到没有这样的片段需要重新排列,这意味着所有列表的尾部都被排序,只有头部(第一个元素)可能被放错位置

现在我们寻找像
A->B->…
的片段,其中
A>B
。由于只有头可能放错了位置,而
A
显然放错了位置,那么
A
就是头,即A没有子项。因此,我们可以从
A
开始遍历列表,找到该列表中
A
应该放在哪里,然后将
A
移动到那里,无需将
A
的子项更新为
A
即可保证没有子项

下面是一个在随机数据上运行的示例:

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->

我将创建一个
映射
,它通过其父节点映射每个
指针
(实际上是一个边的
映射
),但根节点需要单独存储。之后,您可以通过重复遍历图来重构
列表
,直到找不到进一步的映射为止

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;
}
公共集合组(集合指针){
if(指针.isEmpty()){
返回集合。emptyList();
}
列表根=新的ArrayList();
Map parents=newhashmap(pointers.size());
for(指针:指针){
if(指针.hasParent()){
parents.put(指针.getParent(),指针);
}否则{
root.add(指针);
}
}
列表结果=新的ArrayList(roots.size());
for(指针根:根){
列表=新建LinkedList();
list.add(根目录);
指针当前=父.get(根);
while(当前!=null){
列表。添加(当前);
当前=父项。获取(当前);
}
结果。添加(列表);
}
返回结果;
}
对于您给定的输入:

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 
指针a=新指针(“a”);
指针c=新指针(“c”,a);
指针d=新指针(“d”,c);
指针b=新指针(“b”);
指针e=新指针(“e”,b);
指针f=新指针(“f”);
集合指针=数组.asList(a,b,c,d,e,f);
集合分组=组(指针);
//结果:A->C->D;B->E;F

谢谢,我想我现有的解决方案已经足够优化了,除了使用地图的更改。您还可以创建已知大小的集合(请参见代码)。对于
映射
,有
指针.size()
节点减去根的数量。但是,因为我预计只有几个根,这应该是一个很好的估计。
result
的大小也是已知的。嗨,这个“函数”的目的不是物理上的“排序”,因为没有任何东西需要排序。问题是从节点的原始指针重建链表,那么函数的输出是什么?它是否应该为每个指针分配一个列表ID,以便属于同一列表的指针具有相同的列表ID,而属于不同列表的指针具有不同的列表ID?或者它应该输出一组集合,其中每个集合对应一个lin