第一次在csdn求助!不知道规矩,希望各位大佬能够指点!谢谢大家!
下面是题目和代码,输入完两个集合以后输出两次并集就会出错,还有一个问题是怎么清空链表??
被这两个问题折磨了一星期le
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct node {
int data;
struct node* next;
}node;
int lenth(node* head);
node* build();//创建链表
int IN_SET(node* p, node* head);//判断新元素是否在链表中存在
node* INSERT_SET(node* head);//插入链表
void output0(node* head);
int compare(node* p, node* tail);
node* Plus(node* head1, node* head2);
int IN_SET(node* head1, node* head2);
node* Cross(node* head1, node* head2);
node* Oppo(node* head1, node* head2);
int main()
{
node* LA = NULL;
node* LB = NULL;
node* head_c = NULL;
node* head_d = NULL;
node* head_e = NULL;
int item;
while (1)
{
system("color 9");
printf("\n0-退出 1-编写集合 2-插入元素 3-输出集合");
printf("\n4-输出交集 5-输出并集 6-输出对称差 \n");
printf("请选择要进行的操作:");
scanf("%d", &item);
switch (item)
{
case(0):
{
exit(0);
}
case(1):
{
if (LA != NULL)
{
printf("已经存在链表!!");
break;
}
printf("\n创建集合A:");
LA = build();
printf("\n创建完毕");
printf("\n创建集合B:");
LB = build();
printf("\n创建完毕");
break;
}
case(2):
{
int t;
printf("\n输入1将元素插入集合A,输入2将元素插入集合B:");
scanf("%d", &t);
switch (t)
{
case(1):
{
LA = INSERT_SET(LA);
node* temp1 = LA;
while (temp1 != NULL)
{
printf("%d ", temp1->data);
temp1 = temp1->next;
}
break;
}
case(2):
{
LB = INSERT_SET(LB);
break;
}
}
break;
}
case(3):
{
printf("\n输出A集合:\n");
output0(LA);
printf("\n输出B集合:\n");
output0(LB);
break;
}
case(4):
{
printf("\nA与B的交集为:\n");
head_d = Cross(LA, LB);
output0(head_d);
break;
}
case(5):
{
printf("A与B的并集为:\n");
head_c = Plus(LA, LB);
output0(head_c);
break;
}
case(6):
{
printf("A与B的对称差为:\n");
head_e = Oppo(LA, LB);
output0(head_e);
break;
}
}
}
}
node* build()
{
int size, n = 0;
node* head = NULL, * newnode = NULL;
//node* MoveP = head;
//node* EXMoveP = head;
printf("\n请输入该集合大小:");
scanf("%d", &size);
while (n < size)
{
n++;
newnode = (node*)malloc(sizeof(node));
newnode->next = NULL;
//printf("\n请输入你想增加的元素:");
//scanf("%d", &(newnode->data));
if (head == NULL)//头指针为空,则替换头指针中的值
{
printf("\n请输入你想增加的元素:");
scanf("%d", &(newnode->data));
head = newnode;
continue;
}
head = INSERT_SET(head);//用插入排序进行输入
}
// MoveP = head;//(测试)输出链表,查看链表存储方式
//
// while (MoveP!=NULL)
// {
// printf("%d ", MoveP->data);
// MoveP = MoveP->next;
// }
return head;
}
void output0(node * head)//输出函数,已排序的数组从尾部倒着输出
{
node* tempnode = head;
int len = lenth(head);
if (tempnode == NULL)
{
printf("空集");
return;
}
for (int i = 0; i < len; i++)
{
node* tail = head;
for (int j = len; (j - i - 1) > 0; j--)
{
tail = tail->next;
}
printf("%d ", tail->data);
}
}
int compare(node * p, node * tail)//比较两个传入节点的值的大小 ,前者大于后 者,则返回0,否则返回1。
{
if (tail == NULL) return 0;
if ((p->data) > (tail->data)) return 0;
return 1;
}
node* INSERT_SET(node * head)//插入链表
{
node* Head = head, * tail = head;
if (head == NULL)//头指针为空,则说明创建链表不成功,或者未创建链表
{
// printf("②");
printf("尚未创建集合,请重新输入");
return head;
}
while ((tail->next) != NULL)//将尾指针挪到正确位置
{
tail = tail->next;
}
while (1)//无限循环,以下每一种条件都会有出口
{
node* p = (node*)malloc(sizeof(p));
p->next = NULL;
printf("\n请输入插入的元素:");
scanf("%d", &(p->data));
if (!IN_SET(head, p))//判断新元素是否已经存在
{
printf("\n该元素已在集合中,请重新输入另一个值");
free(p);
continue;
}
else
{
if ((p->data) > (tail->data))//如果新元素大于尾部,直接接上
{
tail->next = p;
tail = p;
return head;
}
else
{
node* MoveP = (head->next);//操作指针,用于插入操作的时候连接后半部分链表
node* EXMoveP = head;//操作指针的前一指针,保证能够比较到每一个值
if ((p->data) < (head->data))//如果新元素比头部要小,则插在头部之前
{
(p->next) = head;
head = p;
return head;
}
while ((EXMoveP->next) != NULL)
{
if ((p->data) < (MoveP->data))//如果比操作指针要小,则插在操作指针前
{
(EXMoveP->next) = p;//先替换掉操作指针前一个指针的next入口,这两行不能打乱次序
(p->next) = MoveP;
return head;
}
MoveP = (MoveP->next);
EXMoveP = (EXMoveP->next);//向后拨动指针
}
}
}
}
}
node* INSERT_SET0(node* head,node* newnode)//插入链表
{
node* Head = head, * tail = head;
if (head == NULL)//头指针为空,则说明创建链表不成功,或者未创建链表
{
return head;
}
while ((tail->next) != NULL)//将尾指针挪到正确位置
{
tail = tail->next;
}
while (1)//无限循环,以下每一种条件都会有出口
{
node* p = (node*)malloc(sizeof(p));
p->data = newnode->data;
p->next = NULL;
if (!IN_SET(head, p))//判断新元素是否已经存在
{
printf("\n该元素已在集合中,请重新输入另一个值");
free(p);
return head;
}
else
{
if ((newnode->data) < (head->data))//尾部插入
{
newnode->next = head;
head = newnode;
return head;
}
if ((p->data) > (tail->data))//如果新元素大于尾部,直接接上
{
tail->next = p;
tail = p;
return head;
}
else
{
node* MoveP = (head->next);//操作指针,用于插入操作的时候连接后半部分链表
node* EXMoveP = head;//操作指针的前一指针,保证能够比较到每一个值
while ((EXMoveP->next) != NULL)
{
if ((p->data) < (MoveP->data))//如果比操作指针要小,则插在操作指针前
{
(EXMoveP->next) = p;//先替换掉操作指针前一个指针的next入口,这两行不能打乱次序
(p->next) = MoveP;
return head;
}
MoveP = (MoveP->next);
EXMoveP = (EXMoveP->next);//向后拨动指针
}
}
}
}
}
node* Plus(node * head1, node * head2)//取并集
{
node* Head1 = head1, * Head2 = head2, * head3 = NULL, * p1 = NULL, * New_tail = NULL;
while (Head1 != NULL)
{
node* p1 = (node*)malloc(sizeof(p1));
p1->next = NULL;
(p1->data) = (Head1->data);
if (head3 == NULL)//令头部和尾部先重合,以创建新链表
{
head3 = p1;
New_tail = p1;
}
else
{
New_tail->next = p1;
New_tail = p1;
}
Head1 = Head1->next;
}
Head1 = head1;
while (Head2 != NULL)
{
if (IN_SET(Head1, Head2))//如果Head1(整个链表)和Head2(一个节点)的值不一样,执行,将不一样的值插入新构建的链表中
{
head3=INSERT_SET0(head3, Head2);
}
Head2 = Head2->next;
}
return head3;
}
int IN_SET(node * head1, node * head2)//在head1为头部的链表中查找是否有与head2节点的值相等的节点,有返回假(0),没有返回真(1)
{
node* Head1 = head1, * Head2 = head2;
while (Head1 != NULL)
{
if ((Head1->data) == (Head2->data))
return 0;
Head1 = Head1->next;
}
return 1;
}
node* Cross(node * head1, node * head2)//取交集
{
node* Head1 = head1, * Head2 = head2, * head3 = NULL, * p1 = NULL, * New_tail = NULL;
while (Head2 != NULL)
{
if (0 == IN_SET(Head1, Head2))//若 Head1链表中有与Head2相同的节点,取出,拼接成为新节点
{
node* p1 = (node*)malloc(sizeof(p1));
p1->next = NULL;
(p1->data) = (Head2->data);
if (head3 == NULL)
{
head3 = p1;
New_tail = p1;
}
else
{
New_tail->next = p1;
New_tail = p1;
}
}
Head2 = Head2->next;
}
return head3;
}
node* Oppo(node * head1, node * head2)//求对称差
{
node* head3 = NULL, * head4 = NULL, * head5 = NULL, * p1 = NULL, * New_tail = NULL;
head4 = Plus(head1, head2);
head3 = Cross(head1, head2);
while (head4 != NULL)
{
if (IN_SET(head3, head4))//如果head3与head4链表中的元素不相同,执行
{
node* p1 = (node*)malloc(sizeof(p1));
p1->next = NULL;
(p1->data) = (head4->data);//把不相同的元素取出,组成新的链表
if (head5 == NULL)
{
head5 = p1;
New_tail = p1;
}
else
{
New_tail->next = p1;
New_tail = p1;
}
}
head4 = head4->next;
}
return head5;
}
int lenth(node * head)//计算链表长度的函数
{
node* temp = head;
int i = 0;
while (temp != NULL)
{
i++;
temp = (temp->next);
}
return i;
}