📅  最后修改于: 2023-12-03 15:40:55.201000             🧑  作者: Mango
本文将详细介绍如何使用 Java 编写用于链接列表的合并排序程序。关于合并排序算法的原理和概念,在此不再赘述,读者可自行了解。
我们可以使用递归算法来实现链表的合并排序。具体方法如下:
定义一个 mergeSort
方法,输入参数为链表头结点 ListNode
,返回值也为 ListNode
。
检查链表的长度是否大于1。如果小于等于1,直接返回该链表头结点。
如果链表长度大于1,找到链表的中间结点。可以使用两个指针,一个指针每次移动一步,另一个指针每次移动两步,直到快指针移动到链表尾部或者快指针的下一个结点为链表尾部时,慢指针指向的结点即为链表的中间结点。
将链表分为两个部分,前半部分以中间结点为结尾,后半部分以中间结点的下一个结点为开头。
递归调用 mergeSort
方法对前半部分链表进行排序,返回排序好的链表头结点。
递归调用 mergeSort
方法对后半部分链表进行排序,返回排序好的链表头结点。
将前半部分链表和后半部分链表进行合并。可以使用一个 merge
方法,输入两个链表的头结点,返回合并后的链表的头结点。合并的过程就是不断比较两个链表的头结点,将较小的结点放到新链表中,直到其中一个链表为空。
返回合并好的链表的头结点。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode mid = getMid(head);
ListNode l1 = head;
ListNode l2 = mid.next;
mid.next = null;
l1 = sortList(l1);
l2 = sortList(l2);
return merge(l1, l2);
}
private ListNode getMid(ListNode head) {
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
private ListNode merge(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(-1);
ListNode cur = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
if (l1 != null) {
cur.next = l1;
}
if (l2 != null) {
cur.next = l2;
}
return dummy.next;
}
}
在本文中,我们通过递归算法实现了用于链接列表的合并排序程序。这种算法虽然不是最优解,但是代码简单易懂,容易实现。读者可以根据自己的需要进行拓展和优化。