我有两个班级:
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; ..
答案 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循环迭代:
curr = {“ant”} a = {“bat”,“dog”} b = {“cat”,“lion”,“rat”}
curr = {“ant”,“bat”} a = {“dog”} b = {“cat”,“lion”,“rat”}
curr = {“ant”“bat”,“cat”} a = {“dog”} b = {“lion”,“rat”}
curr = {“ant”,“bat”,“cat”,“dog”} a = {} b = {“lion”,“rat”}
a == null,while循环终止
接下来发生了什么? 您的方法只从列表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;
}