您的位置:首页 > 编程语言 > Java开发

LintCode 98-链表排序

2017-01-02 16:04 281 查看

本人电子系,只为一学生。心喜计算机,小编以怡情。

在 O(n log n) 时间复杂度和常数级的空间复杂度下给链表排序。

样例

给出 1->3->2->null,给它排序变成 1->2->3->null.

感悟:要求 O(n log n) 时间复杂度,然后我上网查了一下别的博主的博客的前言,发现只能用并归排序来做,我又查了一下并归排序,然后写出了之后的又臭又长的代码。不过用链表来做排序,那真是超级酸爽。。。

思路:我是以1,2,4,8…….为并归的单位

public ListNode sortList(ListNode head) {
// write your code here
if(head==null||head.next==null) return head;

int len=getlength(head);//得到长度

ListNode realhead=new ListNode(0);//人为的加一个头结点
realhead.next=head;

ListNode flag=realhead;//为了不每次都从头开始查找
//我们定义一个flag,比如132null,当并归2与null时,flag指向3

for(int i=1;i<len;i*=2)//外层控制总次数1,2,4,8,....
{
flag=realhead;
ListNode pre=flag.next;
ListNode last=flag;
//内层是分别的2,4,8,16
while(last!=null)
{
int count=i;
pre=flag.next;
last=pre;
while(last!=null&&count--!=0)
{
last=last.next;
}//last指向要并归的片段首部,比如12345,长度为2时的片段
//pre指向1,last指向3

//因为等会要切成片,会丢失关系,因此给5做个引用,使链表能够恢复
ListNode a=flag;
int linshi=i*2+1;
while(a!=null&&linshi--!=0)
a=a.next;
//////
//切片
slash(pre, i);
slash(last, i);
//after slash we need reconnect;
ListNode temp=merge(pre, last);//整合切片
flag.next=temp;让flag指向头部,这样联系就建立起来了
//flag de dingwei
count=2*i;
while(flag!=null&&count--!=0)
{
flag=flag.next;
}//移动flag,这样不用每次都从头部找东西了,此例flag指向4
//再将联系按上
if (flag==null) {//flag可能出现null情况
break;
}
flag.next=a;//让4指向5,切片断掉的联系就连上了
}
}
return realhead.next;
}

//将两个以null结尾的链表整合到一个并返回头部
static ListNode merge(ListNode head,ListNode last)
{
if(last==null) return head;
if(head==null) return last;
ListNode ret=head;//fanhui xiaozhi

ListNode temphead=new ListNode(0);
temphead.next=head;
ListNode pre=temphead;

while(last!=null)
{
ListNode temp2=last.next;
while(pre.next!=null&&pre.next.val<last.val)
{
pre=pre.next;
}

ListNode t=pre.next;
pre.next=last;
last.next=t;
last=temp2;
}
return temphead.next;
}

//将链表以1,2,4.。。。等单位划分为小片(用于并归排序)
//就是将最后一个元素.next=null
static  void slash(ListNode head,int count)
{
while(head!=null&&--count!=0)
{
head=head.next;
}
if(head!=null)
head.next=null;
}

static int getlength(ListNode head)//获得链表长度函数
{
int count=0;
while(head!=null)
{
count++;
head=head.next;
}
return count;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LintCode Java