Write code to partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x.
写代码把一个链表根据值x分成两块,来使得所有小于x的节点都在大等于x的节点的前面。
例如:
1->3->7->5->2->9->4 按照5来分 变成:
1->3->2->4->7->5->9 这样所有小于5的都在大等于5之前了
思路:
建立两个链表,第一个存放比x小的节点,第二个存放大等于x的节点。
最后合并两个链表。这样做法还是in place的
package LinkLists;
import CtCILibrary.LinkedListNode;
public class S2_4 {
// 建立两个链表,第一个存放比x小的节点,第二个存放大等于x的节点
public static LinkedListNode partition(LinkedListNode node, int x) {
LinkedListNode beforeStart = null; // 第一个链表开始位置
LinkedListNode beforeEnd = null; // 第一个链表结束位置
LinkedListNode afterStart = null; // 第二个链表开始位置
LinkedListNode afterEnd = null; // 第二个链表结束位置
while (node != null) {
LinkedListNode next = node.next; // 保存下一个节点
node.next = null; // 断开当前节点和下一个节点连接
if(node.data < x) { // 小的被分到第一个链表
if(beforeStart == null) { // 链表还没建时
beforeStart = node;
beforeEnd = beforeStart;
} else{ // 链表已经存在时
beforeEnd.next = node;
beforeEnd = node;
}
} else{ // 大的被分到第二个链表
if(afterStart == null) {
afterStart = node;
afterEnd = afterStart;
} else{
afterEnd.next = node;
afterEnd = node;
}
}
node = next;
}
if(beforeStart == null) { // 所有的节点都大于x
return afterStart;
}
beforeEnd.next = afterStart; // 连接两个链表
return beforeStart;
}
// 另一种方法,书中说的是能避免使用多个变量。
// 但我觉得这种方法没什么意义,因为这种方法反而会更慢些,而且合并出来的也不是stable的
// 为了完整性,也把这种解法附在这里。思想是链表的头插代替上面的尾插
public static LinkedListNode partition2(LinkedListNode node, int x) {
LinkedListNode beforeStart = null;
LinkedListNode afterStart = null;
/* Partition list */
while (node != null) {
LinkedListNode next = node.next;
if (node.data < x) {
/* Insert node into start of before list */
node.next = beforeStart;
beforeStart = node;
} else {
/* Insert node into front of after list */
node.next = afterStart;
afterStart = node;
}
node = next;
}
/* Merge before list and after list */
if (beforeStart == null) {
return afterStart;
}
LinkedListNode head = beforeStart;
while (beforeStart.next != null) {
beforeStart = beforeStart.next;
}
beforeStart.next = afterStart;
return head;
}
public static void main(String[] args) {
/* Create linked list */
int[] vals = {1, 3, 7, 5, 2, 9, 4};
LinkedListNode head = new LinkedListNode(vals[0], null, null);
LinkedListNode current = head;
for (int i = 1; i < vals.length; i++) {
current = new LinkedListNode(vals[i], null, current);
}
System.out.println(head.printForward());
LinkedListNode clone = head.clone();
/* Partition */
LinkedListNode h = partition(head, 5);
LinkedListNode h2 = partition2(clone, 5);
/* Print Result */
System.out.println(h.printForward());
System.out.println(h2.printForward());
}
}