Java 链表排序问题
是的,这是一个家庭作业项目。 也就是说,我希望从我的错误中吸取教训,而不仅仅是让别人帮我 我的项目是一个词频列表-我接受一个文本文件(或网站URL)并计算:Java 链表排序问题,java,list,sorting,Java,List,Sorting,是的,这是一个家庭作业项目。 也就是说,我希望从我的错误中吸取教训,而不仅仅是让别人帮我 我的项目是一个词频列表-我接受一个文本文件(或网站URL)并计算: -唯一字数,和 -它们出现了多少次 所有方法都为我提供,只有一个除外:insert(E-word)方法,其中参数是泛型词。 单词存储在一个节点(链表项目)中,该节点也有一个“count”值,该值表示单词在正在读取的文本中出现的次数 此方法必须执行以下操作: 如果参数已经在列表中,则增加该元素的计数。我已经完成了这部分 如果在列表中找不到参数
-唯一字数,和
-它们出现了多少次 所有方法都为我提供,只有一个除外:
insert(E-word)
方法,其中参数是泛型词。
单词存储在一个节点(链表项目)中,该节点也有一个“count”值,该值表示单词在正在读取的文本中出现的次数
此方法必须执行以下操作:
NullPointerExceptions
。这是我当前的插入方法:
public void insert(E word){
if(word.equals("")){
return;
}
if(first == null){//if list is null (no elements)
/*Node item = new Node(word);
first = item;*/
first = new Node(word);
}
else{//first != null
Node itemToAdd = new Node(word);
boolean inList = false;
for(Node x = first; x != null; x=x.next){
if (x.key.equals(word)){// if word is found in list
x.count++;//incr
inList = true;//found in list
break;//get out of for
}//end IF
if(x.next == null && inList == false){//if end of list && not found
x.next = itemToAdd;//add to end of list
break;
}//end IF
}//end FOR
//EVERYTHING ABOVE THIS LINE WORKS.
if (!isSorted()){
countSort();
}
}//end ELSE
}//end method
public void countSort(){
for (Node x = first, p = x.next; p != null; x=x.next, p=p.next){
// x will start at the first Node, P will always be 1 node ahead of X.
if(x == first && (x.count < p.count)){
Node oldfirst = first;
x.next = p.next;
first = p;
first.next = oldfirst;
break;
}
if (x.count < p.count){
//copy.next == x.
Node oldfirst = first;
oldfirst.next = first.next;
x.next = p.next;
first = p;
first.next = oldfirst;
break;
}
if (x.count == p.count){
if(x.toString().charAt(0) < p.toString().charAt(0)){
//[x]->[p]->[q]
Node oldfirst = first;
x.next = p.next;
first = p;
first.next = oldfirst;
break;
}
}
}
}
我的isSorted()
方法:
public boolean isSorted(){
for(Node copy = first; copy.next != null; copy = copy.next){
if (copy.count < copy.next.count){
return false;
}
}
return true;
}
我最初的想法是尝试循环if(!isSorted()){countSort();}
部分,直到它被排序为止,但我在这样做时似乎遇到了一个无限循环。我试着听教授的讲稿,但不幸的是,他把上一堂课的讲稿贴了两遍,所以我不知所措
我不确定这是否值得一提,但他们为我提供了一个迭代器,其中包含方法hasNext()
和next()
——我如何使用它呢?我无法想象他们会提供它,如果它是无用的
我哪里出错了?你很接近。首先,比较项目的函数不完整,因此
isSorted()
可能会产生错误的结果(如果计数相同,但单词顺序错误)。这也用于排序,因此最好提取一种方法进行比较:
// returns a value < 0 if a < b, a value > 0 if a > b and 0 if a == b
public int compare(Node a, Node b) {
if (a.count == b.count)
return a.word.compareTo(b.word);
// case-insensitive: a.word.toLoweCase().compareTo(b.word.toLowerCase())
} else {
return a.count - b.count;
}
}
我们可以借助Java本机库实现或更高效的排序算法,但从练习中判断,排序算法的性能还不重要,首先需要掌握基本概念。通过查看代码,我觉得有两件事可以做到: 首先,您可以使用可比较类方法。所以,我假设您编写了类节点,因此您可能希望从可比较的类继承。当您从该类继承时,java将自动为您提供compareTo方法,您需要做的只是在该方法中指定“我希望根据您的计数进行比较,并且我希望它按升序排列。” **编辑(1):顺便说一句,我忘记了之前提到的内容,但是在您将compareTo方法推进之后,您可以使用Collections.sort(LinkedList列表),它将被完成 想到的第二个解决方案是,您可以在countSort()操作期间对列表进行排序,方法是通过排序将所有列表添加到另一个列表中,然后将所有列表重新添加到真实列表中。我想说的排序技术是,一直到列表的末尾,直到在列表中找到一个节点,该节点的计数小于当前添加节点的计数。希望这不会让你头脑混乱,但通过这种方式,你可以获得更清晰的方法和更少复杂的视图。为了清楚起见,我想重复以下步骤: 看看下一个
如果(next为null),则添加它//您位于末尾。
否则{
如果(计数小于当前计数),则将其添加到该位置
否则,继续移动到下一个节点。//while可用于此操作。
}
你为什么选择链表?@MaxZoom是他的作业,他说。@MaxZoom-教授让我们用链表来做,因为这是我们目前正在学习的数据结构。暂时注释掉//if(x.count==p.count){..}块,然后尝试先按计数排序。也试试看。将while(!sorted){}放入insert方法。我理解您提供的大部分内容,但如果我能看到完整的实施,是否可能。我理解您对第一个解决方案所说的内容,但我相信我在第二个解决方案中可能不清楚。参数中的所有节点的计数均为1,并且仅出现一次(到目前为止)的节点的值也为1。没有节点的计数值小于参数。此外,我还应用了一个ListIterator类-我的主要类声明是:public类Frequency实现了Iterable,因此如果我理解这一点:E泛型扩展了comparable,而Frequency实现了Iterable(我省略了关于字符排序的部分,因为我认为最好从正确的计数排序开始),并再次受到无限循环的欢迎。我不确定在哪里,但我认为在我的代码中的某个地方,我的引用被弄乱了。希望我调试它时不是100多次迭代。@csh1579我添加了多一点代码来说明我的意思,就像这样,你不应该得到无限循环。现在我遇到了一个棘手的问题在整个项目中,我都很紧张-你说要交换x和p,但是如果我不知道导致x的元素,我怎么能交换x和p?正常的过程不是:link x.next to p.next,link p.next to x,link(指向x的元素)to p?我知道你是如何接近它的,但是我们不需要检查以确保x.next.next不是空的吗(或者我错过了这里的要点:P)?@csh1579也正是我首先想到的,但通常检查为x!=null,因为它将在x=x之后进行检查。下一步,因此它与冒泡排序一样正确。oldX==null是唯一的特例。
// returns a value < 0 if a < b, a value > 0 if a > b and 0 if a == b
public int compare(Node a, Node b) {
if (a.count == b.count)
return a.word.compareTo(b.word);
// case-insensitive: a.word.toLoweCase().compareTo(b.word.toLowerCase())
} else {
return a.count - b.count;
}
}
public boolean correctOrder(Node a, Node b) {
if (a.count > b.count)
return true;
else if (a.count < b.count)
return false;
else
return a.word.compareTo(b.word) <= 0;
}
boolean change;
do {
change = false;
Node oldX = null;
// your for:
for (Node x = first; x.next != null; x = x.next) {
if (!correctOrder(x, x.next)) {
// swap x and x.next, if oldX == null then x == first
change = true;
}
oldX = x;
}
} while (change);