我在Java中实现自己的链表。节点类只有一个名为“name”的字符串字段和一个名为“link”的节点。现在我有一个测试驱动程序类,只按顺序插入几个名称。现在,我正在尝试编写一个排序方法来按字母顺序排序节点,但是我遇到了一些麻烦。我从其他人的帖子中发现了这个伪代码,并尝试实现它,但它没有对条目进行完全排序。我不是很确定为什么。任何建议都表示赞赏!
private void sort()
{
//Enter loop only if there are elements in list
boolean swapped = (head != null);
// Only continue loop if a swap is made
while (swapped)
{
swapped = false;
// Maintain pointers
Node curr = head;
Node next = curr.link;
Node prev = null;
// Cannot swap last element with its next
while (next != null)
{
// swap if items in wrong order
if (curr.name.compareTo(next.name) < 0)
{
// notify loop to do one more pass
swapped = true;
// swap elements (swapping head in special case
if (curr == head)
{
head = next;
Node temp = next.link;
next.link = curr;
curr.link = temp;
curr = head;
}
else
{
prev.link = curr.link;
curr.link = next.link;
next.link = curr;
curr = next;
}
}
// move to next element
prev = curr;
curr = curr.link;
next = curr.link;
}
}
}
答案 0 :(得分:4)
我花了一些时间来看你的代码是否有错误,但没有找到。
我会说,直到有人更聪明或更努力地工作,你应该尝试自己调试。如果您有像Eclipse这样的IDE,您可以在观察变量值时单步执行代码;如果没有,你可以在几个地方插入印刷语句,并用你期望的东西手工检查你看到的内容。
更新我
我复制了你的代码并进行了测试。除了它按降序排序(可能不是你想要的)之外,它对于0,1和10个随机节点的样本非常有效。那问题出在哪里?
更新II
还在猜测“它不能完全对条目进行排序”。您可能期望进行词典排序(即'B'之前的'a'),而且对于具有混合大写/小写的单词而言,这不是按计划出现的。在这种情况下,解决方案是使用String
方法compareToIgnoreCase(String str)
。
答案 1 :(得分:0)
这可能不是您正在寻找的解决方案,但它很简单。也许你像我一样懒惰。
由于您的节点只包含一个数据项,因此您不需要重新调整节点;您可以简单地交换节点上的值,同时保持列表的结构本身不受干扰。
这样,你可以很自由地实现冒泡排序。
答案 2 :(得分:0)
您应该使用该语言提供的排序程序。
基本上,你需要你的元素类来实现java.lang.Comparable,你将只委托给obj.name.compareTo(other.name)
然后您可以使用Collections.sort(yourCollection)
或者你可以创建一个知道如何比较对象的java.util.Comparator
答案 3 :(得分:0)
要获得良好的性能,您可以使用Merge Sort。 它的时间复杂度为O(n * log(n)),可以在没有列表内存开销的情况下实现。
冒泡排序不是很好的排序方法。您可以阅读What is a bubble sort good for?了解详情。
答案 4 :(得分:0)
这可能有点太晚了。我会通过插入所有内容来构建列表,因为排序链表并不好玩。
我很肯定你的老师或教授不希望你使用java的本机库。不过话说回来,没有真正快速的方法可以使用这个列表。
您可以按照它们所在的顺序读取所有节点并将它们存储到数组中。对阵列进行排序,然后重新链接节点。我认为Big-Oh的复杂性是O(n ^ 2)所以实际上带链表的冒泡排序就足够了
答案 5 :(得分:0)
我在单链表上完成了合并排序,下面是代码。
public class SortLinkedList {
public static Node sortLinkedList(Node node) {
if (node == null || node.next == null) {
return node;
}
Node fast = node;
Node mid = node;
Node midPrev = node;
while (fast != null && fast.next != null) {
fast = fast.next.next;
midPrev = mid;
mid = mid.next;
}
midPrev.next = null;
Node node1 = sortLinkedList(node);
Node node2 = sortLinkedList(mid);
Node result = mergeTwoSortedLinkedLists(node1, node2);
return result;
}
public static Node mergeTwoSortedLinkedLists(Node node1, Node node2) {
if (null == node1 && node2 != null) {
return node2;
} else if (null == node2 && node1 != null) {
return node1;
} else if (null == node1 && null == node2) {
return null;
} else {
Node result = node1.data <= node2.data ? node1 : node2;
Node prev1 = null;
while (node1 != null && node2 != null) {
if (node1.data <= node2.data) {
prev1 = node1;
node1 = node1.next;
} else {
Node next2 = node2.next;
node2.next = node1;
if (prev1 != null) {
prev1.next = node2;
}
node1 = node2;
node2 = next2;
}
}
if (node1 == null && node2 != null) {
prev1.next = node2;
}
return result;
}
}
public static void traverseNode(Node node) {
while (node != null) {
System.out.print(node + " ");
node = node.next;
}
System.out.println();
}
public static void main(String[] args) {
MyLinkedList ll1 = new MyLinkedList();
ll1.insertAtEnd(10);
ll1.insertAtEnd(2);
ll1.insertAtEnd(20);
ll1.insertAtEnd(4);
ll1.insertAtEnd(9);
ll1.insertAtEnd(7);
ll1.insertAtEnd(15);
ll1.insertAtEnd(-3);
System.out.print("list: ");
ll1.traverse();
System.out.println();
traverseNode(sortLinkedList(ll1.start));
}
}
Node类:
public class Node {
int data;
Node next;
public Node() {
data = 0;
next = null;
}
public Node(int data) {
this.data = data;
}
public int getData() {
return this.data;
}
public Node getNext() {
return this.next;
}
public void setData(int data) {
this.data = data;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "[ " + data + " ]";
}
}
MyLinkedList类:
public class MyLinkedList {
Node start;
public void insertAtEnd(int data) {
Node newNode = new Node(data);
if (start == null) {
start = newNode;
return;
}
Node traverse = start;
while (traverse.getNext() != null) {
traverse = traverse.getNext();
}
traverse.setNext(newNode);
}
public void traverse() {
if (start == null)
System.out.println("List is empty");
else {
Node tempNode = start;
do {
System.out.print(tempNode.getData() + " ");
tempNode = tempNode.getNext();
} while (tempNode != null);
System.out.println();
}
}
}