25. 【C语言】将单链表按照结点的奇偶位置拆分成两个链表(5_task)

问题描述:
将一个链表拆分(将链表奇数位置上的节点构成一个链表,偶数位置上的节点构成另一
个链表)
例如:List:1 -> 2 -> 3 ->4 ->5 ->6 ->7 ->8 ->9 ->10->11-> NULL
List1: 1 ->3 ->5 ->7 ->9 ->11-> NULL ;
List2: 2 ->4 ->6 ->8 ->10-> NULL

算法思想:
用尾插法生成单链表,phead为原始单链表的头指针。设置一个循环,count用于统计当前已遍历的结点个数,同时count是一个数值,pnew指向当前遍历到的结点。count为奇数,那么pnew指向的结点用尾插法插入到链表List1(由头指针phead1指向);count为偶数,那么pnew指向的结点用尾插法插入到链表List2(由头指针phead2指向)。phead不断向后偏移,pnew所指向的结点就尾插到相应的链表后面。最后将各自链表的尾指针(ptail1、ptail2)的指针域置空。
在splitlist( )函数中,原始的头指针不断向后偏移,最终变成空指针,所以形成List打印为空的假象。

案例运行效果:
输入一组数:1 2 3 4 5 6 7 8 9 10 11
在这里插入图片描述
List还没有被拆分前:
在这里插入图片描述
List被拆分后:
在这里插入图片描述
完整代码如下:

#include<stdio.h>
#include<stdlib.h>
typedef struct linklist {
	int data;
	struct linklist *next;
}list,*plist;

void list_create(plist *pphead, plist *pptail, int key)
{
	plist pnew = (plist)calloc(1, sizeof(list));
	pnew->data = key;
	if (NULL == *pphead)
	{
		*pphead = pnew;
		*pptail = pnew;
	}
	else {
		(*pptail)->next = pnew;
		*pptail = pnew;
	}
}

void splitlist(plist *pphead,plist *pphead1,plist *pphead2)
{
	int count = 0;
	plist ptail1, ptail2;
	plist pnew;
	while (*pphead)
	{
		count++;
		pnew = *pphead;
		if (count % 2 )
		{
			if (NULL == *pphead1)
			{
				*pphead1 = pnew;
				ptail1 = pnew;
			}
			else {
				ptail1->next = pnew;
				ptail1 = pnew;;
			}
		}
		else {
			if (NULL == *pphead2)
			{
				*pphead2 = pnew;
				ptail2 = pnew;
			}
			else {
				ptail2->next = pnew;
				ptail2 = pnew;;
			}
		}
		*pphead = (*pphead)->next;
	}
	ptail1->next = NULL;
	ptail2->next = NULL;
}

void list_print(plist p)
{
	while (p)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

int main()
{
	plist phead = NULL , ptail = NULL;
	int key;
	plist phead1 = NULL, phead2 = NULL;
	while (scanf("%d", &key) != EOF)
	{
		list_create(&phead, &ptail, key);
	}
	printf("List:");
	list_print(phead);
	splitlist(&phead, &phead1, &phead2);
	printf("current List:");
	list_print(phead);
	printf("List1:");
	list_print(phead1);
	printf("List2:");
	list_print(phead2);
	system("pause");
}
  • 0
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值