欢迎访问宙启技术站
智能推送

Java函数如何实现对链表元素进行排序

发布时间:2023-05-19 21:52:14

链表是一种常见的数据结构,它的特点是每个节点都包含了一个值和指向下一个节点的指针。链表中的元素是按照插入顺序存储的,但在某些情况下需要对链表元素进行排序。本文将介绍如何使用Java函数实现对链表元素的排序。

1. 插入排序

插入排序是一种简单的排序算法,它适用于小规模数据集。排序思路如下:

- 从 个元素开始,假设它已经排好序

- 取下一个元素并插入有序序列中,使之成为新的有序序列

- 重复上述步骤,直到所有元素都排好序

下面是Java代码实现:

public static void insertionSort(ListNode head) {

    if (head == null) {
        return;
    }

    ListNode dummy = new ListNode(0);
    dummy.next = head;        // 设置哑节点
    ListNode curr = head.next;    // 从第二个节点开始排序
    ListNode lastSorted = head;    // 已排序链表的最后一个节点

    while (curr != null) {

        if (curr.val < lastSorted.val) {        // 如果当前节点比已排序链表的最后一个节点小
            ListNode prev = dummy;        // 从哑节点开始查找插入位置
            while (prev.next.val < curr.val) {
                prev = prev.next;
            }

            lastSorted.next = curr.next;    // 删除当前节点
            curr.next = prev.next;        // 将当前节点插入到prev和prev.next之间
            prev.next = curr;

            curr = lastSorted.next;    // 继续处理下一个节点
        } else {        // 如果当前节点比已排序链表的最后一个节点大
            lastSorted = curr;    // 将当前节点加入到已排序链表中
            curr = curr.next;    // 继续处理下一个节点
        }
    }
}

2. 归并排序

归并排序是一种基于分治思想的排序算法,它适用于大规模数据集。排序思路如下:

- 将待排序序列不断划分为子序列,直至每个子序列中只包含一个元素

- 将相邻的子序列合并,形成含有两个元素的有序序列

- 继续将相邻的有序序列合并,直至所有元素有序排列

下面是Java代码实现:

public static ListNode mergeSort(ListNode head) {

    if (head == null || head.next == null) {
        return head;
    }

    // 快慢指针找到链表中点
    ListNode slow = head, fast = head.next;
    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }

    ListNode right = slow.next;
    slow.next = null;    // 将链表断成两半

    ListNode leftSorted = mergeSort(head);    // 对左半部分排序
    ListNode rightSorted = mergeSort(right);    // 对右半部分排序

    return merge(leftSorted, rightSorted);        // 将两个有序链表合并
}

private static ListNode merge(ListNode left, ListNode right) {

    ListNode dummy = new ListNode(0);
    ListNode curr = dummy;

    while (left != null && right != null) {        // 将两个有序链表合并

        if (left.val < right.val) {
            curr.next = left;
            left = left.next;
        } else {
            curr.next = right;
            right = right.next;
        }

        curr = curr.next;
    }

    curr.next = (left != null) ? left : right;    // 处理剩余的节点

    return dummy.next;
}

3. 快速排序

快速排序也是一种基于分治思想的排序算法,它适用于大规模数据集。排序思路如下:

- 选择基准值,将序列分为两个子序列,一个子序列中的元素都比基准值小,另一个子序列中的元素都比基准值大

- 分别对两个子序列重复上述过程,直至每个子序列只有一个元素或为空

- 合并所有子序列得到排好序的序列

下面是Java代码实现:

public static ListNode quickSort(ListNode head) {
    return quickSortHelper(head, null);
}

private static ListNode quickSortHelper(ListNode head, ListNode tail) {

    if (head == null || head == tail) {    // 如果链表为空或者只有一个元素
        return head;
    }

    ListNode pivot = partition(head, tail);    // 获取基准值

    ListNode left = quickSortHelper(head, pivot);
    ListNode right = quickSortHelper(pivot.next, tail);

    pivot.next = right;    // 连接左子链表、基准值、右子链表

    return (left != null) ? left : pivot;
}

private static ListNode partition(ListNode head, ListNode tail) {

    ListNode prev = head;
    ListNode curr = head.next;

    while (curr != tail) {
        if (curr.val < head.val) {    // 如果当前节点比基准值小
            prev = prev.next;
            swap(prev, curr);        // 交换当前节点与前驱节点
        }
        curr = curr.next;
    }

    swap(prev, head);    // 交换基准值和前驱节点

    return prev;
}

private static void swap(ListNode l1, ListNode l2) {
    int temp = l1.val;
    l1.val = l2.val;
    l2.val = temp;
}

总结

本文介绍了如何使用Java函数实现对链表元素的排序,包括插入排序、归并排序和快速排序。这些排序算法都有其适用场景,选择哪种算法要根据具体情况而定。