目录:
1、题目及分析
1.1 题目
1.2 分析
1、题目及分析
1.1 题目:
Sort a linked list in
O
(
n
log
n
) time using constant space complexity.
1.2 分析
O
(
n
log
n
)的复杂度,所以不能采用冒泡等,这里采用合并排序算法,且为了不采用递归的方式,所以得到如下代码。
2、实现
// Definition for singly-linked list.
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public class SortList {
public int length(ListNode head){ //求链表的长度
int count = 0;
ListNode h = head;
while(null != h){
count ++;
h = h.next;
}
return count;
}
public ListNode sortList(ListNode head) {//返回排序的结果
int len = length(head);
//System.out.println(len);
int window = 2;//
ListNode pointL = null;
ListNode pointR = null;
ListNode tmp = null;
ListNode tmp2 = null;
ListNode headPointer = new ListNode(0); //定义一个头指针
ListNode headPointerTmp = head; //定义一个暂头指针
headPointer.next = head; //将头指针指向传入的链表
headPointerTmp = headPointer; //暂存头指针指向头指针
if(0 == len || 1== len) return head; //如果长度为1,则直接返回
while(window/2 < len){ //二分法每个区间用2^n大小表示,如果len=5,那么必须运算到window=8才能结束
//这里采用 len大于window/2 当len=5时,8/2=4仍然运行,16/2=8才结束
for(int i=len ; i>0; i-=window){
pointL = headPointerTmp;
pointR = headPointerTmp;
for(int k=window/2; k>0; k--){
if(null == pointR.next) break;
pointR = pointR.next;//移动指针
}
for(int j=window/2; j>0; ) {//由于使用分治,所有待排序的,都已经按照一定顺序排列
//R的操作最多window/2次
if(pointR == pointL || null == pointR.next) break; //L中所有都遍历了就结束
if(pointR.next.val < pointL.next.val){//满足条件则进行插入操作
/* pre->A->B->C>D 要将C插入到A之前
* pointL = pre; pointR = C;
* pre->C;C->A;B->D
*/
tmp = pointL.next; //保存A
tmp2 = pointR.next.next; //保存D
pointL.next = pointR.next; //pre->C
pointL.next.next = tmp; //C->A
pointR.next = tmp2; //B->D
pointL = pointL.next; //后移一位
//print(headPointer.next);
j--; //每次进行插入后,进行j--
}
else{
pointL = pointL.next;
}
}
for(int k=window; k>0; k--){ //将指针移动到下一个windonw内
if(null == headPointerTmp.next) break; //这里可以处理非2^n长度的链表
headPointerTmp = headPointerTmp.next;
}
}
window = window * 2; //扩大窗口
headPointerTmp = headPointer;//重新指向最开始
}
return headPointer.next; //返回头结点
}
public void print(ListNode head){
ListNode point = head;
for(int m=length(head); m>0; m--){
System.out.print(point.val + " ");
point = point.next;
}
System.out.println();
}
public static void main(String[] args) {
ListNode l1 = new ListNode(4);
ListNode l2 = new ListNode(2);
ListNode l3 = new ListNode(1);
ListNode l4 = new ListNode(3);
ListNode l5 = new ListNode(5);
ListNode l6 = new ListNode(-1);
ListNode l7 = new ListNode(-2);
ListNode l8 = new ListNode(-100);
ListNode l9 = new ListNode(-1000);
ListNode l10 = new ListNode(-1000);
ListNode k = null;
ListNode lm = null;
SortList s = new SortList();
//k.next = l1;
l1.next = l2;
l2.next = l3;
l3.next = l4;
l4.next = l5;
l5.next = l6;
l6.next = l7;
l7.next = l8;
l8.next = l9;
l9.next = l10;
lm = s.sortList(l1);
s.print(lm);
//System.out.println(lm.val);
//System.out.println(lm.next.val);
}
}