用Java手动排序链表(词法)

时间:2009-12-06 09:27:05

标签: java sorting linked-list

我在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;
            }
        }
    }

6 个答案:

答案 0 :(得分:4)

我花了一些时间来看你的代码是否有错误,但没有找到。

我会说,直到有人更聪明或更努力地工作,你应该尝试自己调试。如果您有像Eclipse这样的IDE,您可以在观察变量值时单步执行代码;如果没有,你可以在几个地方插入印刷语句,并用你期望的东西手工检查你看到的内容。


更新我

我复制了你的代码并进行了测试。除了它按降序排序(可能不是你想要的)之外,它对于0,1和10个随机节点的样本非常有效。那问题出在哪里?

更新II

还在猜测“它不能完全对条目进行排序”。您可能期望进行词典排序(即'B'之前的'a'),而且对于具有混合大写/小写的单词而言,这不是按计划出现的。在这种情况下,解决方案是使用String方法compareToIgnoreCase(String str)

答案 1 :(得分:0)

这可能不是您正在寻找的解决方案,但它很简单。也许你像我一样懒惰。

由于您的节点只包含一个数据项,因此您不需要重新调整节点;您可以简单地交换节点上的值,同时保持列表的结构本身不受干扰。

这样,你可以很自由地实现冒泡排序。

答案 2 :(得分:0)

您应该使用该语言提供的排序程序。

try this tutorial.

基本上,你需要你的元素类来实现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();
    }
}

}