Java MergeSort没有给出正确的输出

Java MergeSort没有给出正确的输出,java,linked-list,nodes,mergesort,Java,Linked List,Nodes,Mergesort,我有两门课: public class List { public Node _head; } 以及: 我在“列表”中有一个构造函数,它获取一个字符串作为参数,并将每个单词放在一个单独的节点中,如下所示: public List(String text) { if (text.length() == 0) _head = null; createList(text); } private void createList(String text) {

我有两门课:

public class List {
    public Node _head;
}
以及:

我在“列表”中有一个构造函数,它获取一个字符串作为参数,并将每个单词放在一个单独的节点中,如下所示:

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;
        }
    }
}
公共列表(字符串文本){
如果(text.length()==0)
_head=null;
创建列表(文本);
}
私有void createList(字符串文本){
int lastIndex=0;
字符串温度;

对于(int i=0;i请按如下所示进行更改。我想您忘记了将
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;
    }
公共节点合并(节点a、节点b)
{
节dummyHead,curr;
dummyHead=新节点();
curr=dummyHead;
while(a!=null&&b!=null)
{

如果(a._-word.compareTo(b._-word)合并排序不适用于链表,因为您需要访问列表的中间元素(将列表分为两个子列表)。使用链表,您只能访问列表的第一个元素(单链表)

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

编辑: 昨天,我通过电话回复,无法分析您的代码

今天我测试了你的代码

我用单词
“ant”、“lion”、“pig”、“rat”、“bat”、“tiger”、“cat”、“dog”创建输入列表,并使用
merge\u sort()
方法。 它的输出被很好地排序在列表中

我对代码所做的唯一修改是向
Node()
类添加构造函数

Node () {
    _word = "";
    _next = null;
}

Node (String word) {
    _word = word;
}
但这只是为了让创建新节点更容易

你能告诉我如何测试你的输出列表吗

EDIT2: 我没有检查您的代码以将单词和字符串分开,因为您声明它可以工作)

EDIT3: 您的合并方法还有其他问题,但这是主要问题

当您尝试合并2个列表时,请思考您的
merge()
方法是如何工作的: a={“蚂蚁”、“蝙蝠”、“狗”} b={“猫”、“狮子”、“老鼠”}

while循环迭代:

  • curr={“ant”}a={“bat”、“dog”}b={“cat”、“lion”、“rat”}

  • curr={“蚂蚁”、“蝙蝠”}a={“狗”}b={“猫”、“狮子”、“老鼠”}

  • curr={“蚂蚁”、“蝙蝠”、“猫”}a={“狗”}b={“狮子”、“老鼠”}

  • curr={“蚂蚁”、“蝙蝠”、“猫”、“狗”}a={}b={“狮子”、“老鼠”}

  • a==null,而循环终止

  • 接下来发生了什么? 您的方法只为列表b中的下一个元素分配一次并退出。从列表b中释放第二个元素(“rat”)

    我稍微更改了您的代码,
    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;
    }
    
    公共节点合并排序(节点h){
    if(h._next!=null){//如果列表中至少有2个元素,则检查递归
    节点中间=getMiddle(h);
    节点sHalf=middle.\u next;middle.\u next=null;
    返回merge(mergeSort(h)、mergeSort(sHalf));
    }
    else{//如果只有1个元素,则无需排序
    返回h;
    }
    }
    公共节点合并(节点a、节点b){
    Node dummyHead=新节点();
    节点电流=dummyHead;
    while(a!=null&&b!=null){
    
    如果(一个词)与(二个词)相比你为什么要重新发明链表和排序?难道你不能只使用
    java.util.LinkedList
    java.util.Collections.sort
    ?@kosmaty我想他正在学习实现LinkedList。你有没有试着在排序之前打印数据?只是为了检查你的所有内容是否都在LinkedList中?我正在尝试学习我做了,结果很好(正好相反)。在我尝试排序之后,输出就乱七八糟了。你不是可以通过迭代访问所有元素吗?我想OP使用的是
    getMiddle()
    函数。您使用其他列表的建议是有效的,但用户正在学习实现。请帮助回答问题的要求。我不是说这不可能,而是不合适。对链表使用合并排序是无效的,因为每次划分列表时,都需要通过列表迭代找到中间元素。我明白,这正是用户想要的。他关心的不是程序的有效性,而是对程序的学习。:)我正试图用O(nlogn)来做到这一点@Osh24您能试着打印从
    merge\u sort
    函数得到并传递的值吗?您的意思是在递归函数中添加System.out.print吗?我不确定是哪些值。。
    Node () {
        _word = "";
        _next = null;
    }
    
    Node (String word) {
        _word = word;
    }
    
    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;
    }