在Java中手动排序链表(词汇)
我正在用Java实现我自己的链表。node类只有一个名为“name”的字符串字段和一个名为“link”的节点。现在我有一个测试驱动程序类,它只按顺序插入几个名称。现在,我正在尝试编写一种排序方法来按字母顺序对节点排序,但遇到了一些问题。我从其他人的帖子中找到了bubblesort的伪代码,并试图实现它,但它没有对条目进行完全排序。我不太清楚为什么。任何建议都将不胜感激在Java中手动排序链表(词汇),java,sorting,linked-list,Java,Sorting,Linked List,我正在用Java实现我自己的链表。node类只有一个名为“name”的字符串字段和一个名为“link”的节点。现在我有一个测试驱动程序类,它只按顺序插入几个名称。现在,我正在尝试编写一种排序方法来按字母顺序对节点排序,但遇到了一些问题。我从其他人的帖子中找到了bubblesort的伪代码,并试图实现它,但它没有对条目进行完全排序。我不太清楚为什么。任何建议都将不胜感激 private void sort() { //Enter loop only if there
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;
}
}
}
private void sort()
{
//仅当列表中有元素时才输入loop
布尔交换=(头!=null);
//仅在进行交换时继续循环
while(交换)
{
交换=假;
//维护指针
节点电流=头部;
Node next=curr.link;
Node prev=null;
//无法将最后一个元素与其下一个元素交换
while(下一步!=null)
{
//如果项目顺序错误,则进行交换
if(curr.name.compareTo(next.name)<0)
{
//通知循环再进行一次传递
交换=真;
//交换元件(特殊情况下交换磁头
如果(当前==水头)
{
头=下一个;
节点温度=next.link;
next.link=curr;
当前链接=温度;
curr=头;
}
其他的
{
prev.link=curr.link;
curr.link=next.link;
next.link=curr;
curr=next;
}
}
//移动到下一个元素
上一次=当前;
curr=curr.link;
next=curr.link;
}
}
}
这可能不是您正在寻找的解决方案,但它很好而且简单。也许您和我一样懒惰
由于节点只包含一项数据,因此实际上不需要重新洗牌节点;您可以简单地交换节点上的值,同时保持列表结构本身不受干扰
这样,您就可以非常简单地实现冒泡排序。您应该使用该语言提供的排序过程 基本上,您需要您的元素类来实现java.lang.Comparable,在该类中,您只需委托给
obj.name.compareTo(other.name)
然后,您可以使用Collections.sort(yourCollection)
或者,您可以创建一个java.util.Comparator,它知道如何比较对象,以获得可以使用的良好性能。 它的时间复杂度为O(n*log(n)),可以在不增加列表内存开销的情况下实现
冒泡排序不是一种很好的排序方法。您可以阅读详细信息。我花了几分钟的时间查看您的代码是否有错误,但没有发现错误 我会说,除非有更聪明或更努力的人出现,否则你应该试着自己调试。如果你有像Eclipse这样的IDE,你可以在查看变量值的同时一步完成代码;如果没有,你可以在一些地方插入print语句,并用手检查你所看到的与预期相符的内容
更新I 我复制了你的代码并对其进行了测试。除了它按降序排序(这可能不是你想要的)之外,它对0、1和10个随机节点的样本非常有效。那么问题出在哪里呢 更新II
仍然在猜测“它没有对条目进行完全排序”意味着什么。有可能您期望的是词典排序(即“B”之前的“a”),而对于大小写混合的单词来说,这并没有按计划进行。这种情况下的解决方案是使用
String
方法compareTognoreCase(String str)
这可能有点太晚了。我会先插入所有内容来构建列表,因为对链接列表进行排序并不有趣
我敢肯定你的老师或教授不希望你使用java的本机库。不过,尽管如此,没有真正快速的方法来使用这个列表
您可以按照节点所在的顺序读取所有节点,并将其存储到数组中。对数组进行排序,然后重新链接节点。我认为这一操作的最大复杂性是O(n^2),因此实际上,使用链接列表进行冒泡排序就足够了我已经对单链接列表进行了合并排序,下面是代码
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));
}
}
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();
}
}
}Quote:“我正在用Java实现我自己的链表。”这是一个学习练习,不能通过使用罐装api来完成。问题并不是说这是一个学习练习或不应该使用罐装api。这是你的解释。我的解释是这也是一个学习练习。否则,他就不需要实现一个链表。@Bruno-他可能认为他需要ds来实现链表。如果提问者没有让我们独自面对这个问题,这会容易得多。至于它的价值,我想
你能举一个“没有对条目进行完全排序”的例子吗?你的bubblesort代码看起来不错“compareToIgnoreCase(String str)”这正是我问题的解决方案。不幸的是,我没有注意到我的一些测试数据混合了大小写…我不敢相信我忽略了这么简单的事情。而且,我确实将比较改为“>0”按升序排列,谢谢!哦,很好,我的毅力得到了回报。哦,等等,它没有:不接受,不投票。也没有花,我打赌你甚至不会打电话给我!*嗅嗅*嘿,忘了接受…我没有花,但我最近继承了很多
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();
}
}