Java函数:如何对一个链表进行排序?
发布时间:2023-09-09 14:47:58
要对一个链表进行排序,可以使用一种排序算法,如冒泡排序、插入排序、选择排序、归并排序或快速排序。下面以归并排序为例进行说明。
归并排序是一种分治算法,它将链表不断地分成两半,对这两半进行排序,然后再合并排序好的两半,最终完成链表的排序。归并排序的关键是如何将两个已排序的链表合并成一个有序的链表。
下面是使用归并排序对链表进行排序的Java代码:
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
}
public class SortLinkedList {
public static ListNode sortList(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 secondHalf = slow.next;
slow.next = null;
// 对两个子链表进行排序
ListNode firstHalf = sortList(head);
secondHalf = sortList(secondHalf);
// 合并两个排序好的子链表
return merge(firstHalf, secondHalf);
}
private static ListNode merge(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
curr.next = l1;
l1 = l1.next;
} else {
curr.next = l2;
l2 = l2.next;
}
curr = curr.next;
}
if (l1 != null) {
curr.next = l1;
}
if (l2 != null) {
curr.next = l2;
}
return dummy.next;
}
public static void main(String[] args) {
ListNode head = new ListNode(4);
head.next = new ListNode(2);
head.next.next = new ListNode(1);
head.next.next.next = new ListNode(3);
ListNode sortedList = sortList(head);
while (sortedList != null) {
System.out.print(sortedList.val + " ");
sortedList = sortedList.next;
}
}
}
上述代码中,SortLinkedList类定义了一个链表节点ListNode,其中包含一个整数值val和指向下一个节点的指针next。sortList方法是进行排序的主要方法,它使用递归的方式将链表不断地划分成两半,然后调用merge方法将排序好的两半链表合并。
merge方法接受两个已排序的链表l1和l2,通过比较节点的值,将它们按从小到大的顺序依次连接起来,并返回合并后的链表。
在main方法中,创建一个测试链表head,值分别为4、2、1、3。然后调用sortList方法对链表进行排序,最后打印排序后的结果。
使用归并排序对链表进行排序的时间复杂度为O(n log n),其中n是链表的长度。虽然归并排序的时间复杂度较高,但它是比较稳定的排序算法,适合处理大规模的数据。
