Java 用冒泡排序实现双链表
我正在使用以下命令实现一个Dobly链表:import java.util.LinkedList为赋值使用气泡排序。通过对排序和链表的研究,我了解到我不应该使用索引对链表进行冒泡排序,因为链表中不存在索引,或者成功实现起来太麻烦 因此,在阅读了这些之后,我编写了以下代码,但我仍然不确定我是否走上了正确的道路 我需要一些帮助来理解使用dobly链表实现冒泡排序背后的逻辑 此外,我还需要一些保证,以确定我是否有效地走在正确的道路上,或者我在这个编码练习中的尝试是否完全错误Java 用冒泡排序实现双链表,java,linked-list,bubble-sort,Java,Linked List,Bubble Sort,我正在使用以下命令实现一个Dobly链表:import java.util.LinkedList为赋值使用气泡排序。通过对排序和链表的研究,我了解到我不应该使用索引对链表进行冒泡排序,因为链表中不存在索引,或者成功实现起来太麻烦 因此,在阅读了这些之后,我编写了以下代码,但我仍然不确定我是否走上了正确的道路 我需要一些帮助来理解使用dobly链表实现冒泡排序背后的逻辑 此外,我还需要一些保证,以确定我是否有效地走在正确的道路上,或者我在这个编码练习中的尝试是否完全错误 //This for l
//This for loop sorts the smaller part of the bubble sort.
for(int i = 0; i < cars.size() - 1; i++)
{ //This part creates the second "larger" part of the bubble sort.
for(int j = i + 1; j < cars.size(); j++)
{
//Did I do this part correctly? This is where the swap and sort of the bubble sort takes //place.
//Obviously, I am using the comparable interface, since I am using the compareTo method.
//
//with the bubblesort, all elements must be greater than zero because for the bubble //sort, 0 is the smallest element in a set of integers.
if(cars.get(i).getName().compareTo(cars.get(j).getName()) > 0)
{
CarName cari = cars.get(i);
CarName CarNamej = cars.get(j);
cars.remove(i);
cars.add(i, carj);
cars.remove(j);
cars.add(j, cari);
}
}
}
}
我是对的,还是我在所有代码中都做了一些完全错误的事情?看起来你走的路不对。您需要完全消除索引的使用,而是使用节点引用。首先开发代码,从列表中删除一个元素,只给出对该元素的引用。然后开发代码,将一个元素插入到列表中,就在列表中已经存在的元素之前,只给出对这两个元素的引用。然后可以在这两种方法的基础上构建排序算法 例如,以下是删除元素的方法:
void remove(Element element) {
element.previous().setNext(element.next());
element.next().setPrevious(element.previous());
}
你应该理解双链接列表是如何工作的,来理解为什么这个代码应该在列表中间的元素中工作。根据列表的表示方式,可能需要测试结束条件(
element.previous()
和/或element.next()
为null
)。考虑气泡排序在常规数组上的工作方式。简单的气泡排序实现如下所示:
for (int i = array.Length; i > 0; i--)
{
for (int j = 0; j < i-1; j++)
{
if (array[j] > array[j+1])
{
int tmp = array[j];
array[j] = array[j+1];
array[j+1]=tmp;
}
DisplayElements(array);
}
}
for(int i=array.Length;i>0;i--)
{
对于(int j=0;j数组[j+1])
{
int tmp=数组[j];
数组[j]=数组[j+1];
阵列[j+1]=tmp;
}
显示元素(数组);
}
}
不同之处在于,您必须将对列表中下一个和上一个节点的引用存储在数组或向量中,而不是使用临时int,您可以通过索引访问存储的变量,即项目列表中的位置 在链表中,您可以通过从一个项目跳到下一个项目来访问特定项目 由于您在代码中使用的是
get(i)
,因此在按列表中的位置进行索引时,显然使用的是数组或向量。所以,不。。。不幸的是,你完全走错了方向
一旦您越来越接近,您的代码将更像:
boolean changed = true;
while (changed) { // keep going until we didn't make any more changes (not
// strictly the best condition for bubble sort, but it'll do)
a = first; // grab first element
b = a.next; // grab next element
changed = false;
while (b!=last) { // run through all elements
if (a.value>b.value) { // compare the two elements; swap if out of order
a.prev.next = b; // update element before a to be followed by b
b.next.prev = a; // update element after b to be preceeded by a
a.prev = b; // b is now before a
b.next = a; // and a is after b
changed = true; // we made a change, so we're not done
} else {
a = b; // if we didn't swap them, move to next pair
}
b = a.next; // second half of next pair is next after a
}
}
这只是给你一个粗略的想法。它绝不是完整的或没有bug的。例如,如果您在列表的最开始处,则需要首先更新a.prev
,而不是a.prev.next=b行中的a.prev
,等等。。。但是嘿。。。反正你也不想让别人帮你做作业,对吧?;)
基本上,在双链接列表中,每个元素都知道如何到达下一个元素(a.next)和上一个元素(a.prev)。气泡排序是对这种链表进行排序的一种很好的选择,因为它只比较相邻的元素。否则,快速排序或合并排序或两者的组合可能会快得多,但它们确实需要对元素进行索引访问,而链表通常不提供这种访问
希望这有帮助
顺便说一句:Youtube上有一大堆很酷的视频,很好地解释了这些事情
还有一个更严重的问题:
还有一个更不寻常的例子:(其中一个用于快速排序的有更好的音乐:)为什么不将链表转换成数组,对数组进行排序,然后将内容复制回链表中。我认为你应该先用一种方法完成这个问题,然后询问是否有问题这就是问题所在,我正在以整数格式对一组数据进行排序,所以如果我使用bubbleSort的编码方式不是更好吗?根据我从参考资料中了解到的情况,LinkedList允许您不必关心要排序的信息的索引。因此,您只能关注信息本身。如果不使用数组进行冒泡排序,交换节点不是效率低下吗?@edxyz-也许我误解了。我的印象是您正在实现自己的双链接列表结构。如果您使用的是java.util.LinkedList
,那么您当前的方法是好的。但是,我建议使用set
而不是remove
,然后使用add
。是的。我正在使用import java.util.LinkedList;但我只需要澄清一下我的编码所涉及的逻辑,以确保我在正确的轨道上。在上面的代码中,我对逻辑的各个部分添加了更多的注释和解释。谢谢你。@edxyz-看起来基本上是对的。您似乎有一个输入错误,将变量命名为caramej
,而不是carj
。另外,正如我所说,我建议使用cars.set(I,carj)代码>而不是车辆。删除(i)代码>后接cars.add(i,carj)代码>,位置j
。是的,我知道使用数组进行冒泡排序是什么样子。谢谢你给我提神。我会记住这一点,并进一步理解我的代码。唯一要记住的是您使用的数据结构的差异。数组是按顺序排列的,而链表是按结构中的引用排列的。感谢视频。Java API内置了将列表转换为数组的方法,反之亦然。
boolean changed = true;
while (changed) { // keep going until we didn't make any more changes (not
// strictly the best condition for bubble sort, but it'll do)
a = first; // grab first element
b = a.next; // grab next element
changed = false;
while (b!=last) { // run through all elements
if (a.value>b.value) { // compare the two elements; swap if out of order
a.prev.next = b; // update element before a to be followed by b
b.next.prev = a; // update element after b to be preceeded by a
a.prev = b; // b is now before a
b.next = a; // and a is after b
changed = true; // we made a change, so we're not done
} else {
a = b; // if we didn't swap them, move to next pair
}
b = a.next; // second half of next pair is next after a
}
}