import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
public ListNode sortInList (ListNode head) {
// write code here
//方法一:快速排序,利用辅助数组,使用数组工具类对数组排序
//特殊值处理,当链表为空或者链表的长度为1时,直接返回原链表的头指针
// if(head == null || head.next == null){
// return head;
// }
// ListNode head0 = head;
// ArrayList<Integer> arrayList = new ArrayList<>();//创建一个ArrayList
// //遍历链表,将链表中的值保存在列表中
// while (head0 != null){
// arrayList.add(head0.val);
// head0 = head0.next;
// }
// head0 = head;
// final Object[] objects = arrayList.toArray();//将列表转换为数组
// int len = arrayList.size();
// int[] arr = new int[len];
// for(int i=0;i<len;i++){//将Object[]数组转换为整型数组int[]
// arr[i] = (int) objects[i];
// }
// Arrays.sort(arr);//利用数组工具类Arrays对整型数组int[]排序
// int index = 0;
// while (head0 != null){//将排好序的值放回到原来的链表中
// head0.val = arr[index];
// index++;
// head0 = head0.next;
// }
// return head; //返回原链表的头指针
//方法二:归并排序,使用递归,先对链表分割成长度小于3的子链表,排序,再将排好序的链表排序
if(head == null || head.next == null){
return head;
}
ListNode head0 = head;
int count = countNode(head0);
head0 = head;
ListNode root = mergeSort(head0, count);
return root;
}
/**
* 题目描述:找出链表的中点节点
* @param pHead 链表的头节点
* @param len 链表节点的个数
* @return 返回链表的中点节点的指针
*/
public static ListNode findMiddlePosition(ListNode pHead,int len){
int count = len/2;
ListNode temp = pHead;
while (count > 1){
temp = temp.next;
count--;
}
return temp;
}
/**
* 题目描述:计算出链表节点的个数
* @param pHead 链表的头指针
* @return 返回链表的节点个数
*/
public static int countNode(ListNode pHead){
ListNode temp = pHead;
int count = 0; //计数器
while (temp != null){
count++;
temp = temp.next;
}
return count;
}
/**
* 题目描述:输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。
* eg:1->3->5; ==>1->2->3->4->5->6
* 2->4->6;
* @param list1 链表1
* @param list2 链表1
* @return 返回合并后的链表头节点
*/
public static ListNode Merge(ListNode list1,ListNode list2) {
//特殊值处理,list1为空,返回链表2的头节点
if(list1 == null){
return list2;
}
//特殊值处理,list2为空,返回链表1的头节点
if(list2 == null){
return list1;
}
ListNode head = null;//合并后的链表头节点
//初始化头节点
if(list1.val <= list2.val){
head = list1;
list1 = list1.next;
}else {
head = list2;
list2 = list2.next;
}
ListNode head0 = head;//初始化合并后的链表的尾节点
while (list1 != null && list2 != null){//当链表1和链表2都不为空时,比较两个链表的最小值
if(list1.val <= list2.val){//链表1的最小值小于链表2的最小值
head0.next = list1; //合并后的链表的尾节点指向链表1的头节点
head0 = head0.next; //更新合并后的链表的尾节点
list1 = list1.next; //更新链表1的头节点
}else {
head0.next = list2; //合并后的链表的尾节点指向链表2的头节点
head0 = head0.next; //更新合并后的链表的尾节点
list2 = list2.next; //更新链表2的头节点
}
}
if(list1!=null){//当链表1不为空时,合并后的链表的尾节点指向链表1的头节点
head0.next = list1;
}
if(list2!=null){//当链链表2不为空时,合并后的链表的尾节点指向链表2的头节点
head0.next = list2;
}
return head;//返回合并后的链表的头节点
}
/**
* 题目描述:合并两个链表,使得节点值顺序排序,先分割,然后排序,最后合并
* @param pHead 链表的头节点
* @param len 链表的长度
* @return 返回节点值顺序排序后链表的头指针
*/
public static ListNode mergeSort(ListNode pHead,int len){
ListNode left = null; //保存左边链表的头指针
ListNode right = null; //保存右边链表的头指针
ListNode head0 = pHead; //临时头指针
if(len > 2){//当链表的长度大于2时,链表需要分割
final ListNode middlePosition = findMiddlePosition(head0, len);//找出链表的中间位置,返回值是左边链表的尾节点
// head0 = pHead; //左边链表临时头指针
right = middlePosition.next; //保存右边链表的头指针
middlePosition.next = null; //切断链表
final int leftCount = countNode(head0); //计算左边链表的长度
// head0 = pHead; //左边链表临时头指针
left = mergeSort(head0, leftCount); //对左边链表进行合并排序
ListNode right0 = right; //右边链表临时头指针
final int rightCount = countNode(right0); //计算右边链表的长度
// right0 = right; //右边链表临时头指针
right = mergeSort(right0,rightCount); //对右边链表进行合并排序
left = Merge(left,right);//合并两个已经排序的链表,合并后的链表值有序
return left; //返回归并后的链表头指针
}
if(len == 1){//当链表的长度等于1时,此时链表已经排好序,直接返回链表的头指针
return pHead;
}
head0 = pHead;
if(len == 2){//当链表的长度等于2时,此时需要对链表的两个节点排序,然后返回链表的头指针
if(head0.val > head0.next.val){
int temp0 = head0.val;
head0.val = head0.next.val;
head0.next.val = temp0;
}
}
return pHead;
}
}
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
public ListNode sortInList (ListNode head) {
// write code here
//方法一:快速排序,利用辅助数组,使用数组工具类对数组排序
//特殊值处理,当链表为空或者链表的长度为1时,直接返回原链表的头指针
// if(head == null || head.next == null){
// return head;
// }
// ListNode head0 = head;
// ArrayList<Integer> arrayList = new ArrayList<>();//创建一个ArrayList
// //遍历链表,将链表中的值保存在列表中
// while (head0 != null){
// arrayList.add(head0.val);
// head0 = head0.next;
// }
// head0 = head;
// final Object[] objects = arrayList.toArray();//将列表转换为数组
// int len = arrayList.size();
// int[] arr = new int[len];
// for(int i=0;i<len;i++){//将Object[]数组转换为整型数组int[]
// arr[i] = (int) objects[i];
// }
// Arrays.sort(arr);//利用数组工具类Arrays对整型数组int[]排序
// int index = 0;
// while (head0 != null){//将排好序的值放回到原来的链表中
// head0.val = arr[index];
// index++;
// head0 = head0.next;
// }
// return head; //返回原链表的头指针
//方法二:归并排序,使用递归,先对链表分割成长度小于3的子链表,排序,再将排好序的链表排序
if(head == null || head.next == null){
return head;
}
ListNode head0 = head;
int count = countNode(head0);
head0 = head;
ListNode root = mergeSort(head0, count);
return root;
}
/**
* 题目描述:找出链表的中点节点
* @param pHead 链表的头节点
* @param len 链表节点的个数
* @return 返回链表的中点节点的指针
*/
public static ListNode findMiddlePosition(ListNode pHead,int len){
int count = len/2;
ListNode temp = pHead;
while (count > 1){
temp = temp.next;
count--;
}
return temp;
}
/**
* 题目描述:计算出链表节点的个数
* @param pHead 链表的头指针
* @return 返回链表的节点个数
*/
public static int countNode(ListNode pHead){
ListNode temp = pHead;
int count = 0; //计数器
while (temp != null){
count++;
temp = temp.next;
}
return count;
}
/**
* 题目描述:输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。
* eg:1->3->5; ==>1->2->3->4->5->6
* 2->4->6;
* @param list1 链表1
* @param list2 链表1
* @return 返回合并后的链表头节点
*/
public static ListNode Merge(ListNode list1,ListNode list2) {
//特殊值处理,list1为空,返回链表2的头节点
if(list1 == null){
return list2;
}
//特殊值处理,list2为空,返回链表1的头节点
if(list2 == null){
return list1;
}
ListNode head = null;//合并后的链表头节点
//初始化头节点
if(list1.val <= list2.val){
head = list1;
list1 = list1.next;
}else {
head = list2;
list2 = list2.next;
}
ListNode head0 = head;//初始化合并后的链表的尾节点
while (list1 != null && list2 != null){//当链表1和链表2都不为空时,比较两个链表的最小值
if(list1.val <= list2.val){//链表1的最小值小于链表2的最小值
head0.next = list1; //合并后的链表的尾节点指向链表1的头节点
head0 = head0.next; //更新合并后的链表的尾节点
list1 = list1.next; //更新链表1的头节点
}else {
head0.next = list2; //合并后的链表的尾节点指向链表2的头节点
head0 = head0.next; //更新合并后的链表的尾节点
list2 = list2.next; //更新链表2的头节点
}
}
if(list1!=null){//当链表1不为空时,合并后的链表的尾节点指向链表1的头节点
head0.next = list1;
}
if(list2!=null){//当链链表2不为空时,合并后的链表的尾节点指向链表2的头节点
head0.next = list2;
}
return head;//返回合并后的链表的头节点
}
/**
* 题目描述:合并两个链表,使得节点值顺序排序,先分割,然后排序,最后合并
* @param pHead 链表的头节点
* @param len 链表的长度
* @return 返回节点值顺序排序后链表的头指针
*/
public static ListNode mergeSort(ListNode pHead,int len){
ListNode left = null; //保存左边链表的头指针
ListNode right = null; //保存右边链表的头指针
ListNode head0 = pHead; //临时头指针
if(len > 2){//当链表的长度大于2时,链表需要分割
final ListNode middlePosition = findMiddlePosition(head0, len);//找出链表的中间位置,返回值是左边链表的尾节点
// head0 = pHead; //左边链表临时头指针
right = middlePosition.next; //保存右边链表的头指针
middlePosition.next = null; //切断链表
final int leftCount = countNode(head0); //计算左边链表的长度
// head0 = pHead; //左边链表临时头指针
left = mergeSort(head0, leftCount); //对左边链表进行合并排序
ListNode right0 = right; //右边链表临时头指针
final int rightCount = countNode(right0); //计算右边链表的长度
// right0 = right; //右边链表临时头指针
right = mergeSort(right0,rightCount); //对右边链表进行合并排序
left = Merge(left,right);//合并两个已经排序的链表,合并后的链表值有序
return left; //返回归并后的链表头指针
}
if(len == 1){//当链表的长度等于1时,此时链表已经排好序,直接返回链表的头指针
return pHead;
}
head0 = pHead;
if(len == 2){//当链表的长度等于2时,此时需要对链表的两个节点排序,然后返回链表的头指针
if(head0.val > head0.next.val){
int temp0 = head0.val;
head0.val = head0.next.val;
head0.next.val = temp0;
}
}
return pHead;
}
}