MergeSort没有给出正确的输出

时间:2015-06-21 20:26:38

标签: java linked-list nodes mergesort

我有两个班级:

public class List {
    public Node _head;
}

public class Node {
    public String _word;
    public Node _next;
}

我在" List"中有一个构造函数,它获取一个String作为参数,并将每个单词放在一个单独的节点中,如下所示:

public List(String text) {
    if (text.length() == 0)
        _head = null;
    createList(text);
}

private void createList(String text) {
    int lastIndex=0; 
    String temp;        
    for (int i=0;i<text.length();i++) {
        if (text.charAt(i)==' '|| i==text.length()-1) {
            if (i == 0) { // Space in the begining
                lastIndex=1;
                continue;
            }
            if (i == text.length()-1) { // If we reached to the last char of the string

                if (text.charAt(i) == ' ') { // If it's a space, don't include it
                    temp = text.substring(lastIndex,i);
                } else {
                    temp = text.substring(lastIndex,i+1);
                }
            } else {
                temp = text.substring(lastIndex,i);
            }
            addToBegining(temp);
            lastIndex=i+1;
        }
    }
}

无论如何,当我试图在链表上使用合并时,我无法设法让它运转起来。

这是排序代码:

public Node merge_sort(Node h) {
    if (h == null || h._next == null) { return h; }
    Node middle = getMiddle(h);      //get the middle of the list
    Node sHalf = middle._next; middle._next = null;   //split the list into two halfs

    return merge(merge_sort(h), merge_sort(sHalf));  //recurse on that
}

public Node merge(Node a, Node b) {
    Node dummyHead, curr; 
    dummyHead = new Node(); 
    curr = dummyHead;
    while (a !=null && b!= null) {
        if (a._word.compareTo(b._word) <= 0) { 
            curr._next = a; 
            a = a._next; 
        } else { 
            curr._next = b; 
            b = b._next; 
        }
        curr = curr._next;
    }
    curr._next = (a == null) ? b : a;
    return dummyHead._next;
}

public Node getMiddle(Node h) {
    if (h == null) { return h; }
    Node slow, fast; 
    slow = fast = h;
    while (fast._next != null && fast._next._next != null) {
        slow = slow._next; 
        fast = fast._next._next;
    }
    return slow;
}

知道什么是错的吗? 我试图使用String&#34; Hello New World A Dawn Is There&#34;来创建一个新的TextList。和输出是:&#34;世界&#34; ..

2 个答案:

答案 0 :(得分:0)

请更改如下。我想您忘记在curr之后将if-else节点分配给适当的值。

    public Node merge(Node a, Node b)
    {
        Node dummyHead, curr;
        dummyHead = new Node();
        curr = dummyHead;
        while (a != null && b != null)
        {
            if (a._word.compareTo(b._word) <= 0)
            {
                curr._next = a;
                curr = a;
                a = a._next;
            }
            else
            {
                curr._next = b;
                curr = b;
                b = b._next;
            }
            curr = curr._next;
        }
        curr._next = (a == null) ? b : a;
        return dummyHead._next;
    }

答案 1 :(得分:-1)

合并排序不适合链接列表,因为您需要访问列表的中间元素(将列表分成2个子列表)。使用链接列表,您只能访问列表的第一个元素(单链表)。

尝试使用它是不可行的,因为每次分割列表时都必须首先找到中间元素的链接。最好尝试插入排序或快速排序,链接列表的第一个元素作为一个支点。

修改 昨天,我用手机回复,无法分析你的代码。

今天我测试了你的代码。

我使用单词"ant", "lion", "pig", "rat", "bat", "tiger", "cat", "dog"创建输入列表并使用merge_sort()方法。 它的输出是很好的排序列表。

我所做的代码的唯一变化是向Node()

添加构造函数
Node () {
    _word = "";
    _next = null;
}

Node (String word) {
    _word = word;
}

但这只是让我更容易创建新节点。

您能说明如何测试输出列表吗?

<强> EDIT2: 我没有检查你的代码,如你所说的那样将单词与字符串分开)

<强> EDIT3: 你的合并方法还有其他问题,但这个是主要问题。

当您尝试合并2个列表时,请考虑merge()方法是如何工作的: a = {“ant”,“bat”,“dog”} b = {“cat”,“lion”,“rat”}

while循环迭代:

  1. curr = {“ant”} a = {“bat”,“dog”} b = {“cat”,“lion”,“rat”}

  2. curr = {“ant”,“bat”} a = {“dog”} b = {“cat”,“lion”,“rat”}

  3. curr = {“ant”“bat”,“cat”} a = {“dog”} b = {“lion”,“rat”}

  4. curr = {“ant”,“bat”,“cat”,“dog”} a = {} b = {“lion”,“rat”}

  5. a == null,while循环终止

  6. 接下来发生了什么? 您的方法只从列表b中分配一次下一个元素并退出。从b。

    中失去第二个元素(“老鼠”)

    我稍微更改了您的代码,getMiddle()方法与您的相同:

    public Node mergeSort(Node h) {
        if (h._next != null) { // check for recursion if in list left at least 2 elements
            Node middle = getMiddle(h);
            Node sHalf = middle._next; middle._next = null;
            return merge(mergeSort(h), mergeSort(sHalf));
        }
        else { // if only 1 element then no need to sort
            return h;
        }
    }
    
    public Node merge(Node a, Node b) {
        Node dummyHead = new Node();
        Node curr = dummyHead; 
        while (a !=null && b!= null) {
            if (a._word.compareTo(b._word) <= 0) {
                curr._next= a; 
                a = a._next; 
            } else { 
                curr._next = b; 
                b = b._next;            
            }
            curr = curr._next;
        }
        // if list a still has some elements, insert them to the end of the curr
        while(a != null) {
            curr._next = a; 
            a = a._next; 
            curr = curr._next;
        }
        // if list b still has some elements, insert them to the end of the curr
        while(b != null) {
            curr._next = b; 
            b = b._next;
            curr = curr._next;
        }
        return dummyHead._next;
    }