package com.abuge;
/**
* 需求:
* 对一个链表进行排序,要求时间复杂度为O(nlogn),空间复杂度为O(1)
* @author AbuGe
*思路:
*1、利用数组存储链表的节点值
*2、通过比较节点的属性值,利用快速排序重新排列节点值
*3、重构链表顺序
*
*注:考虑空链表和一个节点的情况,注意空指针异常
*定义数组不能为空。
*/
class ListNode
{
int val;
ListNode next;
ListNode(int x)
{
val = x;
next = null;
}
}
public class SortList
{
//快速排序,挖坑+填数法
public static int adjustArray(ListNode[] nodeArray, int left, int right)
{
//第一步:确定排序区间及基准值
int i = left;
int j = right;
ListNode base = nodeArray[i];
//循环遍历
while(i < j)
{
//第二步:从后向前遍历
while(i < j && base.val <= nodeArray[j].val)
{
j--;
}
if(i < j)
{
nodeArray[i] = nodeArray[j];
i++;
}
//第三步:从前向后遍历
while(i < j && base.val >= nodeArray[i].val)
{
i++;
}
if(i < j)
{
nodeArray[j] = nodeArray[i];
j--;
}
}
//第四步:确定基准值
nodeArray[i] = base;
return i;
}
public static void quickSort(ListNode[] nodeArray, int left, int right)
{
//递归使用数组调整
if(left < right)
{
//先挖坑填数,将数组分成两部分,获得分区下标i
int i = adjustArray(nodeArray, left, right);
//左区间递归调整
quickSort(nodeArray, left, i - 1);
//右区间递归调整
quickSort(nodeArray, i + 1, right);
}
}
public static ListNode sortList(ListNode head)
{
//考虑空指针情况
if(head == null)
return null;
//定义数组时不能指定为空,需要为其赋初值
ListNode[] nodeArray = new ListNode[65536];
ListNode last = head;
int i = 0;
//遍历链表,将节点存储到数组中
while(last != null)//注意判断条件
{
nodeArray[i] = last;
last = last.next;
i++;
}
if(head.next == null)
{
nodeArray[0] = head;
i = 1;
}
//进行快速排序
int len = i;
quickSort(nodeArray, 0, len - 1);
//重构链表
for(i = 0; i < len; i++)
{
nodeArray[i].next = nodeArray[i + 1];
}
head = nodeArray[0];
return head;
}
public static void main(String[] args)
{
ListNode head = new ListNode(2);
ListNode last = new ListNode(1);
head.next = last;
ListNode result = sortList(head);
System.out.println(result.val);
}
}