题目:现有一链表的头指针 ListNode pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。*
链表分割
1.分析
- 首先将链表分为前后两段,分割前,分割后
- 定义4个引用
ListNode bs = null;
ListNode be = null;
ListNode as = null;
ListNode ae = null;
3. 定义cur
指向头结点
4. 当cur
不为空,就比较cur.val
和k
的值,如果小于k
,就放在第一段,如果大于k
,就放在第二段
5. 在每一段第一次放入的时候,直接放入就行了,然后cur=cur.next;
6. 在每一段不是第一次插入的时候,采用尾插法,be.next = cur;be = be.next;
或者ae.next = cur; ae = ae.next;
然后cur=cur.next;
7. 第一段可能没数据,直接返回后半段;还有就是原来链表最后一个数据小于k
,那么它应该插在第一段结尾,那么新链表结尾ae.next!=null
,那么要手动置空。
8. 最后返回bs
2.具体步骤
k=15
3.代码
//链表分割
public ListNode partition(int x) {
ListNode bs = null;
ListNode be = null;
ListNode as = null;
ListNode ae = null;
ListNode cur = this.head;
while (cur != null) {
if (cur.val < x) {
//第一次
if (bs == null) {
bs = cur;
be = cur;
} else {
//不是第一次,尾插法
be.next = cur;
be = be.next;
}
} else {
if (as == null) {
as = cur;
ae = cur;
} else {
//不是第一次
ae.next = cur;
ae = ae.next;
}
}
cur = cur.next;
}
//预防第一段为空
if (bs == null) {
return as;
}
be.next = as;
//预防第二段最后一个节点不为空
if (as != null) {
ae.next = null;
}
return bs;
}
测试:
public static void main(String[] args) {
MyLinkedList myLinkedList1 = new MyLinkedList();
myLinkedList1.addLast(12);
myLinkedList1.addLast(3);
myLinkedList1.addLast(34);
myLinkedList1.addLast(5);
myLinkedList1.addLast(56);
ListNode ret=myLinkedList1.partition(15);
myLinkedList1.display2(ret);
}
补充:
方法二 模拟
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
你不需要 保留 每个分区中各节点的初始相对位置。
public ListNode partition(int x) {
ListNode small = new ListNode(-1);
ListNode smallHead = small;
ListNode large = new ListNode(-1);
ListNode largeHead = large;
while (head != null) {
if (head.val <= x) {
small.next = head;
small = small.next;
} else {
large.next = head;
large = large.next;
}
head = head.next;
}
//最大节点节点不再最后
large.next = null;
small.next = largeHead.next;
return smallHead.next;
}