题目描述:
- 现有一链表的头指针 ListNode pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。*
假设给定1,3,8,5,7,4这几个数,x = 5,那么按照题目要求如上图,经过我们的代码就可以将顺序改为1,3,4,5,8,7。 - 我们可以遍历链表,若小于x则尾插到一个新链表,若大于x则尾插到另一个新链表,我们创建两个新的头指针lesshead, greaterhead分别作为两个新链表的头指针,接下来我们画图理清思路:
接下来我们只需要将这两个链表相连即可得到我们想要的顺序:
但是需要注意的是,如图值为7的结点在原链表中指针域是指向值为4的结点的,因此需要断开。
下面是本题的代码:
struct ListNode* partition(ListNode* pHead, int x)
{
struct ListNode* lGuard, *gGuard, *lTail, *gTail;//分别建立头指针和尾指针,头指针便于后续找头用于两个链表链接,尾指针用于尾插数据
lGuard = lTail = (struct ListNode*)malloc(sizeof(struct ListNode));
gGuard = gTail = (struct ListNode*)malloc(sizeof(struct ListNode));
lTail->next = gTail->next = NULL;
struct ListNode* cur = pHead;
while(cur)
{
if(cur->val < x)
{
lTail->next = cur;
lTail = lTail->next;
}
else
{
gTail->next = cur;
gTail = gTail->next;
}//完成数据的分组
cur = cur->next;
}
lTail->next = gGuard->next;//进行两个链表的链接
gTail->next = NULL;//由于最后一个结点在原链表中指向别的结点,我们需要让它指向空,防止链表无尾
pHead = lGuard->next;
free(lGuard);//malloc之后需要释放,防止内存泄漏
free(gGuard);
return pHead;
}
注:1. 代码中两个新链表的创建时分别建了哨兵位头结点(不带数值)和尾结点,是因为我们需要遍历原链表,若只有一个尾结点用于尾插数据,那么最后两个尾结点都会指向最后一个数据,找不到第一个结点的位置,因此我们需要建立一个头指针专门指向第一个结点。2. 之所以要 gTail->next = NULL; 这句话,是最后一个结点在原链表中指向别的结点,我们需要让它指向空,防止链表无尾。