Java 归并排序链表实现

简介

在本文中,我们将学习如何使用Java编程语言实现归并排序算法来对链表进行排序。归并排序是一种分而治之的排序算法,它的基本思想是将原始数组或链表拆分成较小的子数组或子链表,然后对这些子数组或子链表进行排序,最后再将它们合并成一个有序的数组或链表。

归并排序算法步骤

下面是归并排序算法的步骤,我们可以使用一个表格来展示它们:

步骤 描述
步骤 1 将链表拆分成两个较小的链表
步骤 2 递归地对这两个较小的链表进行排序
步骤 3 合并这两个已排序的链表,生成一个有序的链表

现在,我们将逐步解释每个步骤,并提供相应的代码实现。

步骤 1:拆分链表

在这个步骤中,我们需要将原始链表拆分成两个较小的链表。为了实现这一点,我们将使用快慢指针法来找到链表的中点。具体步骤如下:

  1. 定义两个指针,分别为slowfast,并将它们初始化为原始链表的头部。
  2. 使用一个循环,将fast指针向前移动两步,将slow指针向前移动一步,直到fast指针到达链表的末尾。在这个过程中,slow指针将指向链表的中点。

下面是实现这个步骤的Java代码:

/**
 * 拆分链表,返回拆分后的第二个链表的头节点
 * @param head 原始链表的头节点
 * @return 拆分后的第二个链表的头节点
 */
private ListNode split(ListNode head) {
    ListNode slow = head;
    ListNode fast = head;
    
    while (fast.next != null && fast.next.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    
    ListNode secondHead = slow.next;
    slow.next = null;  // 断开链表
    
    return secondHead;
}

步骤 2:递归排序

在这个步骤中,我们将递归地对两个较小的链表进行排序。如果链表的长度小于或等于1,我们将返回链表本身,因为它已经是有序的。否则,我们将递归地对两个较小的链表进行排序,并将它们合并成一个有序的链表。

下面是实现这个步骤的Java代码:

/**
 * 递归地对链表进行归并排序
 * @param head 链表的头节点
 * @return 排序后的链表的头节点
 */
public ListNode mergeSort(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    
    ListNode secondHead = split(head);  // 拆分链表
    
    head = mergeSort(head);  // 递归地对第一个链表进行排序
    secondHead = mergeSort(secondHead);  // 递归地对第二个链表进行排序
    
    return merge(head, secondHead);  // 合并两个有序链表
}

步骤 3:合并链表

在这个步骤中,我们将合并两个已经排序的链表,生成一个有序的链表。为了实现这一点,我们将使用比较两个链表节点的值的方法,并按照从小到大的顺序链接它们。

下面是实现这个步骤的Java代码:

/**
 * 合并两个有序链表
 * @param head1 第一个有序链表的头节点
 * @param head2 第二个有序链表的头节点
 * @return 合并后的有序链表