题目: 编写程序以 x 为基准分割链表,使得所有小于 x 的节点排在大于或等于 x 的节点之前。如果链表中包含 x,x 只需出现在小于 x
的元素之后(如下所示)。分割元素 x 只需处于“右半部分”即可,其不需要被置于左右两部分之间。
思路:
1.定义两个带头结点的链表,这里注意头节点的链表需要初始化,否则会报错!
2.两个带头节点的链表,一个存放小于x的节点。另一个存放大于x和等于x的节点。
3.遍历题目所给的链表,将其分类放到两个带头节点的链表中。
4.最后将两个链表连起来,返回就可以。
这里我定义了一个中间变量,直接标记存放小于x节点的链表的最后一个节点。(标记最后一个节点的办法:因为每次插入都是在带头节点的next中插入,所以当带头节点的next为空时,说明其里面没有元素,直接标记将要插入的元素就可以,这个节点即为最后一个节点。)
在将题目中的所以节点分类完成时,直接将中间变量的next指向存放大于x和等于x的节点的链表。
注意:中间变量需要判空,如果为空,证明没有小于x的节点,返回存放大于x和等于x的节点的链表。
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* partition(struct ListNode* head, int x)
{
if (head == NULL || head->next == NULL)
return head;
struct ListNode newhead1;//存放小于x的节点
struct ListNode newhead2;//存放等于和大于x的节点
newhead1.next = NULL;//带头节点的初始化
newhead2.next = NULL;
struct ListNode* cur = head;
struct ListNode* tmp = NULL;//中间变量
while (cur)
{
//每次循环完都要让cur往后走一步,直接用next标记cur->next,防止链表断开,找不到下一个节点,这里用head=cur->next也可以
struct ListNode* next = cur->next;
if (cur->val < x)
{
if (newhead1.next == NULL)
{
tmp = cur;
}
struct ListNode* cur1 = newhead1.next;
newhead1.next = cur;
cur->next = cur1;
}
else
{
struct ListNode* cur2 = newhead2.next;
newhead2.next = cur;
cur->next = cur2;
}
cur = next;
}
if (tmp != NULL)//如果tmp为空说明没有小于x的节点,返回newhead2.next
{
tmp->next = newhead2.next;
return newhead1.next;
}
return newhead2.next;
}