归并排序
归并排序是运用分治法解决问题的典型范例,基本思想是基于合并操作,即合并两个有序的序列是容易的,合并操作是可以在*O(m+n)*时间内完成。
归并排序的过程如下:
- 首先进行划分,将待排序列划分为大小相等(或大致相等)的两个子序列;
- 当子序列的规模大于1时,递归排序子序列,直到子序列规模为1;
- 将两个有序的子序列合并为一个有序序列。
- 如下图所示,归并排序导致了一系列递归的调用,而这一系列的调用过程可以由一个二叉树表示,每个结点上端白色部分表示递归调用的输入,而下端为递归调用的输出,边上序号表示各个递归调用发生的次序。

代码实现:
import java.util.Arrays;
public class MergeSort {
//合并两个有序区间[p,q][q+1,r]
public static void merge(int[] array, int p, int q, int r) {
//定义一个存放合并后的数组
int[] temp = new int[r-p+1];
//设置两个区间的指针
int s = p;
int t = q+1;
int k =0;
while(s<=q && t<=r) {
if(array[s]<array[t]) {
temp[k++] = array[s++];
} else {
temp[k++] = array[t++];
}
}
while(s<=q) temp[k++] = array[s++];
while(t<=r) temp[k++] = array[t++];
for(int i=0;i<temp.length;i++) {
array[p+i] = temp[i];
}
System.out.println(Arrays.toString(temp));
}
//对[low,high]区间内排序
public static void mergeSort(int[] array, int low, int high) {
if(low<high) {
mergeSort(array,low,(low+high)/2);
mergeSort(array,(low+high)/2+1,high);
merge(array,low,(low+high)/2,high);
}
}
public static void main(String[] args) {
int[] array = {4,8,9,5,2,1,4,6};
mergeSort(array,0,array.length-1);
}
}
归并排序为了将子序列合并,需要使用额外的存储空间,空间复杂度为O(n),时间复杂度为O(nlogn)。
单链表排序
题目描述:给定一个结点数为n的无序单链表头结点head,对其按升序排列,要求时间复杂度为O(nlogn)。
示例
输入:head = [4,2,1,3]
输出:[1,2,3,4]
利用归并排序,思路如下:
- 首先找到当前链表中点(利用快慢双指针法,慢指针指向中点),并从中点将链表断开,得到两个链表;
- 当两个链表的结点数大于1时,递归排序,直到链表节点数为1;
- 最后进行两个 链表的合并。
代码实现:
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
public ListNode sortInList (ListNode head) {
// write code here
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 tmp = slow.next;
slow.next = null;
ListNode left = sortInList(head);
ListNode right = sortInList(tmp);
ListNode h = new ListNode(0);
ListNode res = h;
//合并两个链表
while(left != null && right != null){
if(left.val < right.val){
h.next = left;
left = left.next;
} else{
h.next = right;
right = right.next;
}
h = h.next;
}
h.next = left != null?left:right;
return res.next;
}
}
参考
数据结构与算法(JAVA语言版—周鹏)
如有侵权,请联系
本文深入探讨了归并排序和单链表排序这两种算法。归并排序利用分治策略,通过递归将序列拆分成两部分再合并,时间复杂度为O(nlogn)。单链表排序则结合快慢指针找中点和递归,同样达到O(nlogn)的时间效率。代码实现分别展示了如何在数组和链表场景下应用这两种排序方法。
454

被折叠的 条评论
为什么被折叠?



