已知链表头指针head与数值x,将所有小于x的节点放在大于或等于x 的节点前,且保持这些节点的原来的相对位置。
这个过程有点类似于快速排序,寻找一个阈值,比该阈值小的放左边,比该阈值大的放右边。只是由数组遍历变为来链表遍历,操作变成了指针的指向。
具体步骤如下:
- 创建一个less_ptr,负责对less端的链表进行维护
- 创建一个more_ptr,负责对more端的链表进行维护
- 最终进行less的尾和more的头进行合并,返回头节点。
这个过程需要注意保存less端和more端的头节点,算法实现如下
Data *part_list(Data *head, int n) {
Data less_head;
Data more_head;
less_head.data = 0;
less_head.next = NULL;
more_head.data = 0;
more_head.next = NULL;
Data *less_ptr = &less_head;
Data *more_ptr = &more_head;
/*遍历链表,将大于n的放在右端,小于等于n的放在左端*/
while(head) {
if(head->data > n){
more_ptr->next = head;
more_ptr = head;
} else {
less_ptr->next = head;
less_ptr = head;
}
head = head->next;
}
/*连接小端的尾和大端的头,并将大端的尾置空*/
less_ptr->next = more_head.next;
more_ptr->next = NULL;
/*返回小端的头,因为此时它是链表的表头*/
return less_head.next;
}
源代码测试如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct Link_list
{
/* data */
int data;
struct Link_list *next;
}Data;
/*打印链表*/
void print_list(Data *head) {
while (head) {
printf("%d ",head->data);
head = head -> next;
}
printf("\n");
}
/*尾插法创建链表*/
Data *insert_tail(Data *head, int n) {
head = (Data *)malloc(sizeof(Data));
head->next = NULL;
Data *r = head;
int b;
while(n--){
scanf("%d",&b);
Data *p = (Data *)malloc(sizeof(Data));
p->data = b;
r->next = p;
p->next = NULL;
r = p;
}
return head;
}
/*分割链表*/
Data *part_list(Data *head, int n) {
Data less_head;
Data more_head;
less_head.data = 0;
less_head.next = NULL;
more_head.data = 0;
more_head.next = NULL;
Data *less_ptr = &less_head;
Data *more_ptr = &more_head;
while(head) {
if(head->data > n){
more_ptr->next = head;
more_ptr = head;
} else {
less_ptr->next = head;
less_ptr = head;
}
head = head->next;
}
less_ptr->next = more_head.next;
more_ptr->next = NULL;
return less_head.next;
}
int main(){
Data *head;
int i ,b ;
printf("construct link list :\n");
head = insert_tail(head,5);
Data *test = head -> next;
print_list(test);
printf("after part list :\n");
/*设置3为阈值,大于3的都放在右端,小于等于3的都放在左端*/
Data *part = part_list(head->next,3);
print_list(part);
return 0;
}
输出如下:
construct link list :
5 4 3 2 1
5 4 3 2 1
after part list :
3 2 1 5 4