import java.util.Arrays;
import java.util.ArrayList;

/*
 * 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
        if (null == head) {
            return null;
        }
        if (null == head.next) {
            return head;
        }
        // 定义一个数组,遍历链表,依次将链表中的每个值记录到数组里面去。然后,我们对数组进行快排。最终,重新将数组里面的值赋值到链表上去
        ArrayList<Integer> result = new ArrayList<>();
        // 定义一个辅助指针
        ListNode tp = head;
        while (null != tp) {
            result.add(tp.val);
            tp = tp.next;
        }
        tp = head;
        int[] rs = quickSort(result.stream().mapToInt(Integer::intValue).toArray());
        for (int i = 0; i < rs.length; i++) {
            tp.val = rs[i];
            tp = tp.next;
        }
        return head;
    }
    
    // 快排
    public static int[] quickSort(int[] array) {
        if (0 == array.length || 1 == array.length) {
            return array;
        }
        // 快排的具体实现
        // 荷兰国旗问题
        // 定义一个指针,该指针指向的是小于区域的边界
        int sp = -1;
        // 定义一个指针,该指针指向的是大于区域的边界
        int mp = array.length;
        // 定义一个指针,该指针指向的是当前遍历到的数组的位置
        int np = 0;
        // 定义一个整型变量,用于存放临时数据
        int tmp = 0;
        // 定义一个辅助变量,用于作为交换两个整型变量时的中间值
        int mid = 0;
        // 定义一个比较值,我们这里直接选取的是数组的最后一位上的数字
        int cv = array[array.length - 1];
        // 说明一下,由于我们选取的是数组中的一个数字作为比较值,所以小于区域和大于区域一定不会相遇。在这种情况下,我们选取的循环条件应该是 np != mp
        while (np != mp) {
            tmp = array[np]; // 获取当前位置上的数字
            if (tmp < cv) {
                // 如果小于比较值
                // 将小于区域的右移一位上的数字与该数字进行交换,同时小于区域向右扩充一位,np向右移动一位
                mid = array[np];
                array[np] = array[sp + 1];
                array[sp + 1] = mid;
                sp++;
                np++;
            }
            else if (tmp == cv) {
                np++; // np直接向右移动一位
            }
            else {
                // 如果大于比较值
                // 将大于区域的左移一位上的数字与该数字进行交换,同时大于区域向左扩充一位。注意,np不要动
                mid = array[np];
                array[np] = array[mp - 1];
                array[mp - 1] = mid;
                mp--;
            }
        }
        // 此时,我们解决了荷兰国旗问题
        // 接下来我们要做的事情很简单,就是对小于区域和大于区域也是用相同的处理方式(递归)
        int[] sr = quickSort(Arrays.copyOfRange(array, 0, sp + 1));
        int[] mr = quickSort(Arrays.copyOfRange(array, mp, array.length));
        // 将排好序的小于区域重新赋值到array数组中
        for (int i = 0; i < sr.length; i++) {
            array[i] = sr[i];
        }
        // 将排好序的大于区域重新赋值到array数组中
        for (int i = 0; i < mr.length; i++) {
            array[mp + i] = mr[i];
        }
        // 返回最终的结果
        return array;
    }
}