在一个带头结点的单链表A中,头指针为a,设计算法SplitList ( )将A分解为两个具有相同结构的链表B、C,其中B表的结点为A表中值为奇数的结点,
而C表的结点为A表中值为偶数的结点(链表A的元素类型为整型,要求B、C表除了头结点可以新开辟空间外,其余结点均利用A表的结点,不得申请新的结点空间)最后要求遍历B,C链表。
个人参考学习答案:
void SplitList( LinkList a , LinkList *b , LinkList *c )
{
PNode p = a->next;
PNode b_tail = *b;//链表B尾指针
PNode c_tail = *c;//链表C尾指针
while(p)
{
a->next = p->next;
p->next = NULL;//这两步是摘下p结点
if (p->data % 2 == 0)
{
c_tail->next = p;//p挂c尾
c_tail = p;//尾结点后移==交接
}
else
{
b_tail->next = p;//p挂b尾
b_tail = p;//交接
}
p = a->next;//继续回到链表A中后移,继续循环
}
}
带头结点的单链表结点定义如下:
typedef int DataType;
typedef struct Node
{
DataType data; // data域用于存储数据元素
struct Node *next; // next域用于存放指向其后继的指针
}LNode, *PNode, *LinkList; // LinkList为头指针
函数接口如下:
函数接口如下:
void SplitList( LinkList a , LinkList *b , LinkList *c );
其中 a
,*b
, *c
都是用户传入的参数。 a
是原始链表A的头指针,*b
和*c
是新链表B和C的头指针。
裁判测试程序样例:
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node* next;
}LNode, * PNode, * LinkList;
int InitLinkList(LinkList* head)
{ // 初始化单链表,开辟头结点
*head = (LinkList)malloc(sizeof(LNode));
if (!head)
{
printf("初始化链表错误!\n");
return 0;
}
(*head)->next = NULL;
return 1;
}
PNode LinkListInsert(LinkList h, int pos, DataType x)
{ // 在单链表h的第pos个位置插入x值的元素
PNode p = h, q;
int i = 0;
while (p && i < pos - 1)
{
p = p->next;
i++;
}
if (!p || i > pos - 1)
{
printf("插入位置不合法!\n");
return NULL;
}
q = (PNode)malloc(sizeof(LNode));
if (!q)
{
printf("不能生成新结点\n");
return NULL;
}
q->data = x;
q->next = p->next;
p->next = q;
return q;
}
void DestroyLinkList(LinkList h)
{ // 销毁单链表
PNode p = h->next;
while (h)
{
p = h;
h = h->next;
free(p);
}
}
void TraverseLinkList(LinkList h)
{ // 遍历单链表
PNode p = h->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int BnotinA(LinkList a, LinkList b)
{ // 判链表B的链点是否来自链表A
PNode pb = b->next;
PNode pa = a->next;
if (!pa)
{
return 1;
}
if (!pb)
{
return 1;
}
while (pa)
{
if ((DataType)pb != pa->data)
{
pa = pa->next;
continue;
}
return 0;
}
return 1;
}
// 本题要求完成函数
void SplitList(LinkList a, LinkList* b, LinkList* c);
int main()
{
LinkList aa, aa1, bb, cc;
DataType x;
char ch;
int pos = 1;
PNode pa = NULL;
InitLinkList(&aa);
InitLinkList(&aa1);
InitLinkList(&bb);
InitLinkList(&cc);
do
{
scanf("%d", &x); // 某些编译器要求此处改为scanf_s
pa = LinkListInsert(aa, pos, x);
if (pa != NULL)
{
LinkListInsert(aa1, pos, (DataType)pa);
}
pos++;
} while ((ch = getchar()) != '\n');
SplitList(aa, &bb, &cc);
if ((bb->next == NULL && BnotinA(aa1, cc) != 1) || (cc->next == NULL && BnotinA(aa1, bb) != 1))
{
printf("单链表B和C的链点来自于单链表A!\n");
}
else if ((BnotinA(aa1, bb) != 1) && (BnotinA(aa1, cc) != 1))
{
printf("单链表B和C的链点来自于单链表A!\n");
}
printf("单链表B是\n");
TraverseLinkList(bb);
printf("单链表C是\n");
TraverseLinkList(cc);
DestroyLinkList(aa);
DestroyLinkList(bb);
DestroyLinkList(cc);
return 0;
}
// 你的函数写在此处
输入样例:
12 -9 45 87 -32 64 28 49 34 -42
输出样例:
单链表B和C的链点来自于单链表A!
单链表B是
-9 45 87 49
单链表C是
12 -32 64 28 34 -42