【问题标题】:merging two unsorted singly-linked lists合并两个未排序的单链表
【发布时间】:2023-03-25 01:59:01
【问题描述】:

我写了一个函数来合并两个未排序的单链表。我只是将第二个列表中的每个节点添加到原始列表的前面。它似乎工作,除了当我打印原始的,现在合并的列表时,新添加的元素是'null'

public SLL mergeUnsorted(SLL otherList)
{
    Iterator itr = otherList.iterator() ;
    while (itr.hasNext())
    {
        Object elem  = itr.next() ;
        System.out.println(elem) ; // to make sure the elements are retrieved correctly
        SLLNode ins = new SLLNode(elem, null) ; // make a node out of the element 
        ins.succ = this.first ; // insert the element to the front of the original list
        this.first = ins ;
    }
    return this ;
}

从 main 我调用函数:

myList = myList.mergeUnsorted(otherList) ;
printIt(myList) ;

输出:

null null null null Hi Hello Salut Ciao

SLLNode 构造器:

public SLLNode(Object ObjElem, SLLNode succ)
{
    this.ObjElem = ObjElem ;
    this.succ = succ ;
}

[编辑]

class SLL
{
    SLLNode first ;

    public SLL()
    {
        first = null ;
    }
...

注意 1:练习表明 SLL 类数据表示仅包括第一个节点 private SLLNode first ;,因此我不能使用对“最后一个”节点的任何引用

注意 2:练习包含一个我很可能需要使用但我不知道如何使用的方法。

private SLLNode node(int i)
{
    SLLNode curr = first ;
    for(int j=0; j<i; j++){
        curr = curr.succ ;
        }
    return curr ;
}

注 3:我可以在此处添加迭代器实现代码,但鉴于我可以使用相同的迭代器打印列表,它似乎都是正确的,所以我不想让这篇文章过于混乱。希望没问题?

[EDIT2]

public static void main(String[] args)
{
    SLL myList = new SLL() ;
    SLL otherList = new SLL() ;  
    SLLNode a = new SLLNode("xx", null) ;
    SLLNode b = new SLLNode("yy", null) ;
    SLLNode c = new SLLNode("ww", null) ;
    SLLNode d = new SLLNode("aa", null) ;
    SLLNode e = new SLLNode("rr", null) ;

    otherList.addFirst(a) ;
    printIt(otherList) ;
    otherList.addFirst(b) ;
    printIt(otherList) ;
    otherList.addFirst(c) ;
    printIt(otherList) ;
    otherList.addFirst(d) ;
    printIt(otherList) ;

    SLLNode A = new SLLNode("Hello", null) ;
    SLLNode B = new SLLNode("Hi", null) ;
    SLLNode C = new SLLNode("Salut", null) ;
    SLLNode D = new SLLNode("Ciao", null) ;
    SLLNode E = new SLLNode("Moin", null) ;

    myList.addFirst(A) ;
    printIt(myList) ;
    myList.addFirst(B) ;
    printIt(myList) ;
    myList.addFirst(C) ;
    printIt(myList) ;
    myList.addFirst(D) ;
    printIt(myList) ;

    myList = myList.mergeUnsorted(otherList) ;
    printIt(myList) ;
}

[EDIT3]@Paulo,由包含在 Edit2 中的 main 生成的完整输出

xx
yy xx
ww yy xx
aa ww yy xx
Hello
Hi Hello
Salut Hi Hello
Ciao Salut Hi Hello
aa
ww
yy
xx
null null null null Ciao Salut Hi Hello

请注意,第 9-12 行来自合并函数内的打印语句

【问题讨论】:

  • this.first - 发布SLL类的数据结构。
  • @Baba 当你得到那个输出时,你作为参数给出的两个列表是什么?
  • @Baba 没关系,我从你的帖子中得知有一个列表是 [Hi, Hello, Salut, Ciao]
  • 请放出你的完整代码,从片段中很难发现问题
  • @Baba 向我们展示您的Iterator 实现。

标签: java merge linked-list


【解决方案1】:

为什么不改变实现,所以第一个列表中最后一个节点的后继指向另一个列表中的第一个节点。

public SLL mergeUnsorted(SLL otherList)
{
    if (otherList != null && otherList.first != null) {
        SLLNode last = null;
        Iterator itr = iterator() ;
        for (itr.hasNext())
        {
            Object elem  = itr.next() ;
            if (elem.succ == null) {
                last = elem;
            }
        }
        if (last != null) {
            last.succ = otherList.first;
        }
    }    
    return this;
}

【讨论】:

  • @Baba 'last' 是 mergeUnsorted 方法中的局部变量。您只需在链接列表中查找最后一个元素(添加到列表中的第一个元素),然后将另一个列表链接到第一个元素。
  • 我明白了。这听起来确实是个好主意。我会尝试一下,但首先我想用当前方法解决问题
  • 可以使用SLLNode node(int i) 来查找列表中的最后一个节点(尝试 i=0 并递增直到您没有返回节点——效率不高不过)。
【解决方案2】:

从您的片段来看,它看起来是正确的(但我会使用 this.first = new SLLNode(elem, this.first) 并省略接下来的两个语句)。你的mergeUnsorted 方法打印了什么?


编辑:我不知道出了什么问题,但显然您的 addFirst 方法有效,而直接添加则无法正常工作。所以用这个:

public SLL mergeUnsorted(SLL otherList)
{
    Iterator itr = otherList.iterator() ;
    while (itr.hasNext())
    {
        Object elem  = itr.next() ;
        System.out.println(elem) ; // to make sure the elements are retrieved correctly
        SLLNode ins = new SLLNode(elem, null) ; // make a node out of the element 
        this.addFirst(ins);
    }
    return this ;
}

当然,这会以相反的顺序添加元素,但现在也发生了同样的事情(它只是不起作用)。

【讨论】:

  • @Baba:我想,因为它除了你已经不工作的方法之外什么都不做,只是效率更高一点。但是您的mergeUnsorted 方法会打印什么?
  • @Paulo,请参阅我最初的帖子中的“输出”
  • @Baba:我看到只有一行输出,请复制你程序的整个输出(你刚刚发布的主要方法)。
猜你喜欢
  • 1970-01-01
  • 2017-08-23
  • 2011-01-21
  • 1970-01-01
相关资源
最近更新 更多