1- 思路
归并
- 1- 先求解链表的长度,求出长度后利用
subLen = 1
开始归并
- 定义虚拟头结点
dummyHead
,便于处理头结点
- 2- 归并逻辑 for(int subLen = 1 ; subLen < len;subLen=2)*
- 定义
pre
指针:prev = dummyHead
,用于指向已经合并有序的链表 - 定义
cur
指针:cur = dummyHead.next
,用于链表的拆分 cur
指针用于定位需要归并的链表:利用 cur
指针实现两个链拆分过程
- 3- 链表拆分(在for循环内部)while(cur!=null)
- 3-1 链表1拆分:
- 定义
head1
,从 1
开始遍历到 subLen
,边界条件判断 i<subLen && cur!=null && cur.next!=null
- 3-2 链表2拆分:
2- 实现
⭐148. 排序链表——题解思路
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8b08eee1c41748a182cd1895714d3904.png)
class Solution {
public ListNode sortList(ListNode head) {
int len = 0;
ListNode cur = head;
while(cur!=null){
len++;
cur = cur.next;
}
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
for(int subLen = 1 ; subLen<len;subLen*=2){
ListNode pre = dummyHead;
cur = dummyHead.next;
while(cur!=null){
ListNode head1 = cur;
for(int i = 1 ; i < subLen && cur!=null && cur.next!=null;i++){
cur = cur.next;
}
ListNode head2 = cur.next;
cur.next = null;
cur = head2;
for(int i = 1 ; i < subLen && cur!=null && cur.next!=null ;i++){
cur = cur.next;
}
ListNode tmp = null;
if(cur!=null){
tmp = cur.next;
cur.next = null;
}
pre.next = mergeList(head1,head2);
while(pre.next!=null){
pre = pre.next;
}
cur = tmp;
}
}
return dummyHead.next;
}
private ListNode mergeList(ListNode list1,ListNode list2){
ListNode dummyHead = new ListNode(-1);
ListNode cur = dummyHead;
while(list1!=null && list2!=null){
if(list1.val < list2.val){
cur.next = list1;
list1 = list1.next;
}else{
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
if(list1!=null){
cur.next = list1;
}
if(list2!=null){
cur.next = list2;
}
return dummyHead.next;
}
}
3- ACM 实现
public class sortLink {
public static class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public static ListNode sortList(ListNode head) {
int len = 0;
ListNode cur = head;
while(cur!=null){
len++;
cur = cur.next;
}
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
for(int subLen = 1 ; subLen<len;subLen*=2){
ListNode pre = dummyHead;
cur = dummyHead.next;
while(cur!=null){
ListNode head1 = cur;
for(int i = 1 ; i < subLen && cur!=null && cur.next!=null;i++){
cur = cur.next;
}
ListNode head2 = cur.next;
cur.next = null;
cur = head2;
for(int i = 1 ; i < subLen && cur!=null && cur.next!=null ;i++){
cur = cur.next;
}
ListNode tmp = null;
if(cur!=null){
tmp = cur.next;
cur.next = null;
}
pre.next = mergeList(head1,head2);
while(pre.next!=null){
pre = pre.next;
}
cur = tmp;
}
}
return dummyHead.next;
}
private static ListNode mergeList(ListNode list1,ListNode list2){
ListNode dummyHead = new ListNode(-1);
ListNode cur = dummyHead;
while(list1!=null && list2!=null){
if(list1.val < list2.val){
cur.next = list1;
list1 = list1.next;
}else{
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
if(list1!=null){
cur.next = list1;
}
if(list2!=null){
cur.next = list2;
}
return dummyHead.next;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n1 = sc.nextInt();
ListNode head1 = null, tail1 = null;
for (int i = 0; i < n1; i++) {
int val = sc.nextInt();
ListNode newNode = new ListNode(val);
if (head1 == null) {
head1 = newNode;
tail1 = newNode;
} else {
tail1.next = newNode;
tail1 = newNode;
}
}
ListNode forRes = sortList(head1);
while(forRes!=null){
System.out.print(forRes.val+" ");
forRes = forRes.next;
}
}
}