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函数实现对链表元素的排序,包括插入排序、归并排序和快速排序。这些排序算法都有其适用场景,选择哪种算法要根据具体情况而定。
