25. 【C语言】将单链表按照结点的奇偶位置拆分成两个链表(5_task)
程序员文章站
2022-07-13 17:48:18
...
问题描述:
将一个链表拆分(将链表奇数位置上的节点构成一个链表,偶数位置上的节点构成另一
个链表)
例如: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");
}
上一篇: 中国省市二级联动实现
下一篇: JAVA 实现单向链表的反转