C语言的单链表分割

已知链表头指针head与数值x,将所有小于x的节点放在大于或等于x 的节点前,且保持这些节点的原来的相对位置。
在这里插入图片描述
这个过程有点类似于快速排序,寻找一个阈值,比该阈值小的放左边,比该阈值大的放右边。只是由数组遍历变为来链表遍历,操作变成了指针的指向。

具体步骤如下:

  1. 创建一个less_ptr,负责对less端的链表进行维护
  2. 创建一个more_ptr,负责对more端的链表进行维护
  3. 最终进行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 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值