题目
现给定一链表的头指针 phead 以及值 x,需编写一段代码将所有小于 x 节点的排在其余节点之前,且不能改变原来的数据顺序,最后返回重新排列后的链表的头指针。
算法思想
将小于x的尾插在第一个链表
将大于等于x的尾插在第二个链表
最后将第一个链表的尾指针指向第二个链表的头节点
在这个问题中最重要的是不能改变原来的数据顺序
链表最好带哨兵位能够避免出现空指针问题
代码实现
struct ListNode {
int val;
struct ListNode *next;
}; // 定义一个链表节点结构体,包含一个整型值和指向下一个节点的指针
struct ListNode* Partition(struct ListNode* phead, int x) {
struct ListNode* lesshead; // 小于 x 的节点链表头节点
struct ListNode* lesstail; // 小于 x 的节点链表尾节点
struct ListNode* greaterhead; // 大于等于 x 的节点链表头节点
struct ListNode* greatertail; // 大于等于 x 的节点链表尾节点
lesshead = lesstail = (struct ListNode*)malloc(sizeof(struct ListNode)); // 为小于 x 的节点链表分配头节点
struct ListNode* cur = phead; // 遍历原链表的当前节点
while (cur) { // 遍历原链表
if (cur->val < x) { // 如果当前节点的值小于 x
lesstail->next = cur; // 将当前节点添加到小于 x 的节点链表末尾
lesstail = lesstail->next; // 更新小于 x 的节点链表尾节点
}
else { // 如果当前节点的值大于等于 x
greatertail->next = cur; // 将当前节点添加到大于等于 x 的节点链表末尾
greatertail = greatertail->next; // 更新大于等于 x 的节点链表尾节点
}
cur = cur->next; // 移动到下一个节点
}
lesstail->next = greaterhead->next; // 将小于 x 的节点链表末尾连接到大于等于 x 的节点链表
greatertail->next = NULL; // 设置大于等于 x 的节点链表末尾为 NULL
phead = lesshead->next; // 更新原链表的头节点为小于 x 的节点链表头节点
free(lesshead); // 释放小于 x 的节点链表头节点的内存
free(greaterhead); // 释放大于等于 x 的节点链表头节点的内存
return phead; // 返回重新排列后的链表头节点
}
总结
定义变量:声明了四个指针变量,分别用于表示小于 x 节点链表的头节点、尾节点,大于等于 x 节点链表的头节点和尾节点。
分配头节点:为小于 x 的节点链表分配头节点。
遍历链表:通过循环遍历原始链表。
节点分类:根据节点值与 x 的大小关系,将节点分类插入到相应的链表中。
连接链表:将小于 x 链表的尾节点指向大于等于 x 链表。
设置链表尾节点:将大于等于 x 链表的尾节点设置为 NULL。
更新原链表头节点:更新原链表的头节点为小于 x 的链表头节点。
释放内存:释放小于 x 和大于等于 x 链表头节点的内存。
返回头节点:返回重新排列后的链表头节点。
该方法通过分类插入和连接操作,实现了将小于 x 节点排在其余节点之前的功能,并且保持了原来的数据顺序。