在java中使用单链表和冒泡排序进行编码
Posted
技术标签:
【中文标题】在java中使用单链表和冒泡排序进行编码【英文标题】:coding with a singly linked list and bubble sort in java 【发布时间】:2012-12-09 11:22:33 【问题描述】:我的代码有问题,我创建了一个单链表类,您可以在其中添加、删除、修改、合并等...但是,我正在尝试一个简单的冒泡排序,但遇到了以下问题列表未正确排序。这里有一些注意事项:
它是一个链表的自定义实现 单链表的节点包含两件事:一个包含客户所有数据的 CustomerFile 对象和一个指向列表中下一项的“下一个”节点指针 列表按每个节点的客户文件中存储的姓氏升序 (A-Z) 排序 添加记录功能将节点插入到列表中的正确位置,因此最初不需要对列表进行排序 - 但是如果更改姓氏,作为程序的一部分,列表需要再次排序 我宁愿不创建新列表并在该列表中重复使用此插入记录来创建新列表,因为这会占用大量内存,并且我的任务是尽可能高效 链表的结构本身无法更改 - 已决定,我无法更改为数组之类的东西 列表有一个头节点,它有下一项但没有尾节点。它有一个指定的 NULL next 指针来指示列表的结尾代码
public static void sortList()
if (isEmpty() == true)
System.out.println("Cannot sort - the list is empty");
else if (getHead().getNext() == null)
System.out.println("List sorted");
else
Node current = getHead().getNext();
CustomerFile tempDat;
boolean swapDone = true;
while (swapDone)
current = getHead().getNext();
swapDone = false;
while (current != null)
if (current.getNext() != null &&
current.getData().getSurname().compareTo(
current.getNext().getData().getSurname()) >0)
tempDat = current.getData();
current.setData(current.getNext().getData());
current.getNext().setData(tempDat);
swapDone = true;
current = current.getNext();
if (getHead().getData().getSurname().compareTo(
getHead().getNext().getData().getSurname()) >0)
current = getHead().getNext();
getHead().setNext(current.getNext());
setHead(current);
非常感谢您的反馈
【问题讨论】:
这个方法真的是静态的,没有参数吗?你如何得到你正在排序的列表? 你的列表在什么情况下没有排序? 14358 -> 14358? 14358 -> 13485? 14358 -> 81345? 旧列表“杰伊盖茨比、鲍勃马利、约翰史密斯、齐格星尘”将杰伊盖茨比姓氏更改为“特纳”新列表“鲍勃马利、杰伊特纳、约翰史密斯、齐格星尘”它只循环一次并重新分配一个节点 姓氏存储为大写字母,不区分大小写 【参考方案1】:您的代码是一种奇怪的混合,主要是交换数据,但特别对待头部,试图通过切换链接与下一个交换它。
正如另一个答案中所述,最后一次交换没有正确实现,但如果你通过交换数据来做事,真的没有理由特别对待头部。
您所要做的就是在外循环的头部开始对列表的每次遍历。
这产生了一个可行的解决方案:
public void sortList()
if (isEmpty())
System.out.println("An empty list is already sorted");
else if (getHead().getNext() == null)
System.out.println("A one-element list is already sorted");
else
Node current = getHead();
boolean swapDone = true;
while (swapDone)
swapDone = false;
while (current != null)
if (current.getNext() != null && current.getData().getSurname().compareTo(current.getNext().getData().getSurname()) >0)
CustomerFile tempDat = current.getData();
current.setData(current.getNext().getData());
current.getNext().setData(tempDat);
swapDone = true;
current = current.getNext();
current = getHead();
我已将此设置为非静态,因为正如 cmets 中所述,我不清楚您的静态如何工作。您可以在您的上下文中将其设为静态。
我还更改了其他一些小东西。从来没有必要通过代码来检查条件
if (isEmpty() == true)
在Java中,这完全等价于
if (isEmpty())
并且tempDat
不需要在使用它的地方之外声明。
【讨论】:
【参考方案2】:我认为这里的主要问题是你从头开始
current = getHead().getNext()
使用此代码,您将把头部完全排除在排序过程之外,并且可能此处的数据需要转到列表的另一端,但在这种情况下,它始终是数据在 head 元素中,或者是直接在 head 节点之后的数据(后者是由于你最后的 if 语句)。
尝试从列表的开头开始,看看会带来什么。
【讨论】:
【参考方案3】:您没有在排序中包括头部。
public static void sortList()
if (isEmpty() == true)
System.out.println("Cannot sort - the list is empty");
else if (getHead().getNext() == null)
System.out.println("List sorted");
else
Node current = getHead();
// Node current = getHead().getNext();
CustomerFile tempDat;
boolean swapDone = true;
while (swapDone)
current = getHead().getNext();
swapDone = false;
while (current != null)
if (current.getNext() != null && current.getData().getSurname().compareTo(current.getNext().getData().getSurname()) >0)
tempDat = current.getData(); // td -> objectA, cd -> objectA
current.setData(current.getNext().getData()); // cd -> objectB
current.getNext().setData(tempDat); // nd -> td -> objectA
swapDone = true;
current = current.getNext();
//if (getHead().getData().getSurname().compareTo(getHead().getNext().getData().getSurname()) >0)
//
// current = getHead().getNext(); // current -> head+1
// getHead().setNext(current.getNext()); //head+1 -> head+2
// setHead(current); // head -> head+1
//
上面注释掉的代码也有错误。应用该代码会删除一个节点。
// list: a -> b -> c -> d
current = getHead().getNext(); // current = b
getHead().setNext(current.getNext()); // a -> c
setHead(current); // head = b
// list: b -> c -> d
// and nothing points to 'a' anymore
您应该尝试交换节点,而不是交换数据。如果您采用这种方法,您应该会找到更好的解决方案。
【讨论】:
以上是关于在java中使用单链表和冒泡排序进行编码的主要内容,如果未能解决你的问题,请参考以下文章