链表的冒泡排序算法

13

我编写了一个冒泡排序算法来对链表进行排序。我是Java的初学者,正在尝试学习数据结构。我很困惑为什么我的第二个元素没有被正确地排序。

class SListNode {
    Object item;
    SListNode next;

    SListNode(Object obj) {
        item = obj;
        next = null;
    }

    SListNode(Object obj, SListNode next) {
        item = obj;
        this.next = next;
    }
}
public class SList {
    private SListNode head;
    private SListNode temp;

    public void sortList() {
        SListNode node = head, i, j;
        head = node;
        i = node;
        j = node.next;
        while (i.next != null) {
            while (j.next != null) {
                if ((Integer) i.item < (Integer) j.item) {
                    temp = i.next;
                    i.next = j.next;
                    j.next = temp;
                }
                j = j.next;
            }
            i = i.next;
        }
    }
}

这是我得到的输出

List after construction: [  3  6  9  4  12  15  ]
After sorting: [  3  4  9  12  6  15  ]

除此之外,我知道冒泡排序的最坏时间复杂度是O(n2)。我能在链表上使用归并排序来获得更好的时间复杂度吗?

2个回答

8
有许多排序算法适用于链表,其中归并排序在这种情况下表现出色。我曾经写过一篇关于链表排序的早期回答,其中探讨了许多经典的链表排序算法,以及它们的时间和空间复杂度。你可以在链表上使用插入排序、选择排序、归并排序和快速排序。通过一些调整,你也可以让堆排序正常工作。我的早期回答详细介绍了如何做到这一点。
关于你的代码,请注意,在内部循环中,你将j向前推进,直到next指针变为null。此时,你从未将j重置为其他值,因此在外部循环的每个未来迭代中,内部循环都不会执行。你应该在每次迭代开始时设置j = i.next。此外,你可能不想在j.nextnull时停止循环,而是在jnull时停止循环,否则你将跳过数组的最后一个元素。
此外,你写的排序算法是选择排序,而不是冒泡排序,因为你要在链表上多次遍历以查找尚未定位的最小元素。我不知道这是否是一个问题,但我不确定你是否意识到了这一点。话虽如此,我认为这可能是一件好事,因为在大多数情况下,冒泡排序不如选择排序高效(除非列表已经接近排序)。希望对你有所帮助!

1
如果您有一个ListComparable项组成,那么您可以使用Collections.sort方法,该方法使用一种合并排序算法,具有O(n log n)最坏情况时间复杂度。无论如何,它都比冒泡排序更快,后者的时间复杂度为O(n²)
如果您想使用冒泡排序算法,可以按照以下方式进行:
public static void bubbleSort(List<Integer> list) {
    boolean swapped;
    // repeat the passes through the list until
    // all the elements are in the correct order
    do {
        swapped = false;
        // pass through the list and
        // compare adjacent elements
        for (int i = 0; i < list.size() - 1; i++) {
            // if this element is greater than
            // the next one, then swap them
            if (list.get(i) > list.get(i + 1)) {
                Collections.swap(list, i, i + 1);
                swapped = true;
            }
        }
        // if there are no swapped elements at the
        // current pass, then this is the last pass
    } while (swapped);
}

public static void main(String[] args) {
    LinkedList<Integer> list = new LinkedList<>();
    Collections.addAll(list, 6, 1, 5, 8, 4, 3, 9, 2, 0, 7);
    bubbleSort(list);
    System.out.println(list); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}

另请参阅:
冒泡排序输出不正确
Java 8逐步输出的冒泡排序


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接