1. // 使用额外空间:把链表节点放入数组中,做分区操作类似快排划分,然后再串起来。
    2. public static Node ListPartition1(Node head , int privot){
    3. Node temp = head;
    4. int count = 0;
    5. while(temp != null){
    6. count++;
    7. temp = temp.next;
    8. }
    9. // 构建与node节点等量数组
    10. Node [] list =new Node [count];
    11. temp = head;
    12. // 将链表数拷入数组
    13. for (int i = 0; i < list.length; i++) {
    14. list[i] = temp;
    15. temp = temp.next;
    16. }
    17. // 得到划分完值的
    18. partition(list,privot);
    19. int i=0;
    20. for ( i = 1; i < list.length; i++) {
    21. list[i-1].next =list[i];
    22. }
    23. // 不加上会知一直循环
    24. System.out.println(i);
    25. list[i-1].next = null;
    26. return list[0];
    27. }
    28. public static void partition(Node [] arr , int privot){
    29. int less = -1;
    30. int more = arr.length;
    31. int index = 0;
    32. while(index < more){
    33. if(arr[index].value < privot){
    34. Swap(arr, ++less ,index++);
    35. }else if(arr[index].value > privot){
    36. Swap(arr, --more, index);
    37. }else{
    38. index++;
    39. }
    40. }
    41. }
    42. public static void Swap(Node [] arr,int i,int j){
    43. Node temp = arr[i];
    44. arr[i] = arr[j];
    45. arr[j] = temp;
    46. }
    47. // 不使用额外空间:使用指针来做
    48. // 六个变量,小于部分头尾 SH=null;ST=null; 等于部分头尾EH=null;ET=null;
    49. // 大于部分头尾BH=null;,BT=null;
    50. // 最开始找到的对应的节点头尾都指向,后面再找到的节点改变尾巴并和头串起来。
    51. // 最后小于区域的尾巴连等于区域的头,等于区域的尾巴连大于区域的头。
    52. public static Node Listpartition2(Node head , int privot){
    53. Node sH = null; // small head
    54. Node sT = null; // small tail
    55. Node eH = null; // equal head
    56. Node eT = null; // equal tail
    57. Node mH = null; // big head
    58. Node mT = null; // big tail
    59. Node next = null; // save next node
    60. while (head != null) {
    61. next = head.next;
    62. head.next = null;
    63. if (head.value < privot) {
    64. if (sH == null) { // 第一次找到比privot小的
    65. sH = head;
    66. sT = head;
    67. } else {
    68. sT.next = head; // 不是第一次了,尾巴后驱指向新来的小于pivot节点
    69. sT = head; // 尾巴指向新来的
    70. }
    71. } else if (head.value == privot) {
    72. if (eH == null) {
    73. eH = head;
    74. eT = head;
    75. } else {
    76. eT.next = head;
    77. eT = head;
    78. }
    79. } else {
    80. if (mH == null) {
    81. mH = head;
    82. mT = head;
    83. } else {
    84. mT.next = head;
    85. mT = head;
    86. }
    87. }
    88. head = next;
    89. }
    90. // 小于区域的尾巴,连等于区域的头,等于区域的尾巴连大于区域的头
    91. if (sT != null) { // 如果有小于区域
    92. sT.next = eH;
    93. eT = eT == null ? sT : eT; // 下一步,谁去连大于区域的头,谁就变成eT
    94. }
    95. // 下一步,一定是需要用eT 去接 大于区域的头
    96. // 有等于区域,eT -> 等于区域的尾结点
    97. // 无等于区域,eT -> 小于区域的尾结点
    98. // eT 尽量不为空的尾巴节点
    99. if (eT != null) { // 如果小于区域和等于区域,不是都没有
    100. eT.next = mH;
    101. }
    102. return sH != null ? sH : (eH != null ? eH : mH);// 最后判断返回哪个区域的head
    103. }