69,371
社区成员
发帖
与我相关
我的任务
分享
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
/* 定义结点类型 */
typedef struct Node
{
ElemType data; /* 定义数据域 */
struct Node *next; /* 定义指针域 */
}Node,*LoopLinkList;
/* 循环单链表的创建,采用尾插法建立单链表 */
Node *LinkListCreatT()
{
Node *head,*r,*p;
head = (Node *)malloc (sizeof(Node)); /* 初始化链表 */
if(head == NULL)
{
printf("地址分配失败!\n");
}
r = head ; /* 中间变量 */
ElemType x;
printf("请输入循环链表的元素(以非数字结束,如e):");
while(scanf("%d",&x) == 1) /* 输入数字时scanf返回1 */
{
p = (Node *)malloc(sizeof(Node));
p->data = x;
p->next = r->next;
r->next = p;
r = p; /* 钩链,新创建的结点总是作为最后一个结点 */
}
r->next = head; /* 设置为循环链表 */
return head;
}
int main()
{
LoopLinkList list,start;
list = LinkListCreatT();
for(start = list->next ;start != list;start = start->next)
{
if(start->next == list) /* 判断尾节点的指针域是否为头结点 */
printf("循环链表的最后一个元素:%d",start->data);
}
printf("\n");
return 0;
}
/*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
/*******************************************************************************/
int InPut(); ////集合元素输入
int Action(); ////选择操作函数
int IN_SET(struct Set* head); ////测试集合元素子函数
void Check(struct Set* head); ////测试集合元素主函数
void OutPut(struct Set* head); ////集合元素输出
void DeleteAll(struct Set* head);//释放内存空间
void aa(struct Set* head); ////输出集合A
void bb(struct Set* head); ////输出集合B
void cc(struct Set* head1, struct Set* head2); ////输出交集C
void dd(struct Set* head1, struct Set* head2); ////输出并集D
void ee(struct Set* head1, struct Set* head2); ////输出对称差E
struct Set* JiaoJi(struct Set* head1, struct Set* head2); ////求交集C
struct Set* BingJi(struct Set* head1, struct Set* head2); ////求并集D
struct Set* DCC(struct Set* head1 , struct Set* head2); ////求对称差E
struct Set* INSERT_SET(struct Set* head); ////插入集合元素
struct Set* DeleteNode(struct Set* head, int data); ////删除节点
struct Set* Sort(struct Set* head, struct Set* newnode); ////按非递减方式排序
/*******************************************************************************/
struct Set
{
int data;
struct Set *next;
};
/***主函数**********************************************************************/
int main()
{
return Action();
}
/***选择操作函数****************************************************************/
int Action()
{
int choice,c;
struct Set *a = NULL;
struct Set *b = NULL;
while(1)
{
printf(" 1 : 向集合A添加新元素\n");
printf(" 2 : 向集合B添加新元素\n");
printf(" 3 : 测试集合A的元素\n");
printf(" 4 : 测试集合B的元素\n");
printf(" 5 : 输出集合A的元素\n");
printf(" 6 : 输出集合B的元素\n");
printf(" 7 : 求A、B集合的交集并输出\n");
printf(" 8 : 求A、B集合的并集并输出\n");
printf(" 9 : 求A、B集合的对称差并输出\n");
printf(" 10 : 退出\n\n\n\n请选择您的操作:");
if(scanf("%d", &choice) == 1)
{
switch(choice)
{
case 1: a = INSERT_SET(a); break;
case 2: b = INSERT_SET(b); break;
case 3: Check(a); break;
case 4: Check(b); break;
case 5: aa(a); break;
case 6: bb(b); break;
case 7: cc(a,b); break;
case 8: dd(a,b); break;
case 9: ee(a,b); break;
case 10: DeleteAll(a); DeleteAll(b); return 0; /* 释放内存空间 */
default: printf("您输入的数据不正确,请输入自然数(1~10)\n");
}
}
else /* 输入异常处理,此处输入的数据为字符串,不能正常读取数据 */
{
printf("您输入的数据不正确!请输入整形数据!\n");
}
printf("\n\n\n");
system("pause"); /* 停顿 */
fflush(stdin); /* 清除输入缓冲区,防止不合法数据录入,此函数只是C标准的扩充, */
//while ( (c = getchar()) != '\n' && c != EOF ) ;
system("cls"); /* 调用系统函数实现清屏 */
}/*end of while*/
}
/***函数功能:输入集合元素(集合元素唯一且以非递减方式储存到单链表中)********************/
struct Set *INSERT_SET(struct Set *head)
{
int NewData;
char enter;
printf("请输入集合的元素:");
do /* 利用循环实现多个集合元素一起读入 */
{
int i=0;
NewData = InPut(); /* 调用集合元素输入函数 */
scanf("%c",&enter); /* 利用输入缓冲区的回车键字符来控制循环 */
struct Set *p=NULL, *pr=head;
p = (struct Set *)malloc(sizeof(struct Set));
if(p == NULL)
{
printf("内存不足!\n");
return head;
}
p->next = NULL; /* 置新节点的指针域赋为空 */
p->data = NewData;
while (pr != NULL) /* 遍历链表,保证元素的唯一性 */
{
if(pr->data == NewData)
{
printf("%d已经存在集合中,不再重复记录数据!\n",pr->data);
i=1;
break;
}
pr = pr->next;
}
if(i==0) /* 表示新输入的元素不在原集合中,数据添加成功 */
{
head=Sort(head,p); /* head为表头,p为新插入节点,调用非递减方式排序函数 */
}
} while(enter!='\n');
return head;
}
/***函数功能:集合元素输入**************************************************************/
int InPut()
{
int NewData;
while(1) /* 此循环保证数据类型的合法性 */
{
if(scanf("%d", &NewData)==1)
{
return NewData;
}
char w; /* 防止死循环,影响函数一次性读入多个集合元素的功能 */
scanf("%c",&w); /* 若这个数据不合法,去掉这个数据,再循环读入下一个数据 */
}
}
/***函数功能:以非递减方式排序**********************************************************/
struct Set *Sort(struct Set *head, struct Set *newnode)
{
struct Set *pr=head, *temp=NULL;
if (head == NULL) /* 链表表头为空 */
return newnode; /* 返回新的表头 */
while (pr->data < newnode->data && pr->next != NULL)
{
temp = pr;
pr = pr->next;
}
if (pr->data > newnode->data )
{
if (pr == head) /* 在首节点前插入新节点 */
{
newnode->next = head;
head = newnode;
}
else /* 在链表中间插入 */
{
newnode->next = temp->next;
temp->next = newnode;
}
}
else /* 在表尾插入新节点 */
{
pr->next = newnode;
}
return head;
}
/***函数功能:测试集合元素主函数********************************************************/
void Check(struct Set *head)
{
char i;
printf("请输入您要测试的集合元素:");
do /* 循环控制,实现多个集合元素一次性测试 */
{
int j=IN_SET(head);
if(j==0) /* 调用测试集合元素子函数 */
printf("已经在集合中!\n");
else if(j==1)
printf("不在集合中!\n");
scanf("%c",&i); /* 回车表示输入结束 */
}while(i!='\n');
}
/***函数功能:测试集合元素子函数(集合元素已经在集合中返回0,否则返回1)******************/
int IN_SET(struct Set *head)
{
int data;
if(head == NULL)
{
printf("\n对不起,该链表没有有数据!\n");
return 3;
}
data = InPut(); /* 调用数据输入函数 */
while(head != NULL)
{
if(head->data == data)
{
printf("元素%d",data);
return 0;
}
head = head->next;
}
printf("元素%d",data);
return 1; /* 测试的数据不在集合中 */
}
/***函数功能:输出集合A*****************************************************************/
void aa(struct Set *head)
{
if (head == NULL)
{
printf("集合A为空集!");
return;
}
else
printf("集合A={");
OutPut(head);
printf("}");
}
/***函数功能:输出集合B***************************************************************/
void bb(struct Set *head)
{
if (head == NULL)
{
printf("集合B为空集!");
return;
}
else
printf("集合B={");
OutPut(head);
printf("}");
}
/***函数功能:输出交集C*****************************************************************/
void cc(struct Set* head1, struct Set* head2)
{
head1=JiaoJi(head1,head2); /* 调用求交集函数 */
if (head1 == NULL)
{
printf("交集C为空集!");
return;
}
else
printf("交集C={");
OutPut(head1); /* 调用集合元素输出函数 */
printf("}");
DeleteAll(head1); /* 释放整个链表的内存空间 */
}
/***函数功能:输出并集D***************************************************************/
void dd(struct Set* head1, struct Set* head2)
{
head1=BingJi(head1, head2); /* 调用求并集函数 */
if (head1 == NULL)
{
printf("并集D为空集!");
return;
}
else
printf("并集D={");
OutPut(head1); /* 调用集合元素输出函数 */
printf("}");
DeleteAll(head1); /* 释放整个链表的内存空间 */
}
/***函数功能:输出对称差E*************************************************************/
void ee(struct Set* head1, struct Set* head2)
{
head1=DCC(head1, head2); /* 调用求对称差函数 */
if (head1 == NULL)
{
printf("对称差E为空集!");
return;
}
else
printf("对称差E={");
OutPut(head1); /* 调用集合元素输出函数 */
printf("}");
DeleteAll(head1); /* 释放整个链表的内存空间 */
}
/***函数功能:输出集合元素(集合元素以非递增的方式输出)********************************/
void OutPut(struct Set *head)
{
if (head->next != NULL)
{
OutPut(head->next); /* 递归算法 */
}
if (head->next == NULL) /* 控制输出的第一个元素后面不能再跟逗号"," */
printf("%d",head->data);
else
printf(",%d",head->data); /* 每输出一个元素前面加一个逗号"," */
}
/***函数功能:求集合A和集合B的交集C,并以非递减方式存储********************************/
struct Set *JiaoJi(struct Set *head1, struct Set *head2)
{
struct Set *pr=head1,*p=head2,*c,*head,*temp;
head=c=(struct Set*)malloc(sizeof(struct Set));
head->next = NULL;
while(pr!=NULL) /* 以非递减方式遍历整个集合A,找出交集C并存储到链表C */
{
p=head2; /* 每次都要从表头开始,q为集合B表头 */
while(p!=NULL) /* 内循环遍历集合B */
{
if(pr->data==p->data)
{
temp = (struct Set *)malloc(sizeof(struct Set));
temp->data = pr->data;
temp->next = NULL;
c->next = temp;
c = temp;
break;
}
p=p->next;
}
pr=pr->next;
}
head = head->next;
return head;
}
/***函数功能:求集合A和集合B的并集D******************************************************/
struct Set *BingJi(struct Set *head1, struct Set *head2)
{
struct Set *pr=head1,*p,*q=head2,*head,*d,*temp; /* head表示D链表表头 */
head=d=(struct Set*)malloc(sizeof(struct Set));
head->next = NULL;
while(q!=NULL) /* 以集合B来初始化并集D */
{
temp=(struct Set*)malloc(sizeof(struct Set));
temp->data=q->data;
temp->next=NULL;
d->next=temp;
d=temp;
q=q->next;
}
head = head->next;
while(pr!=NULL) /* 遍历整个集合A,使集合A中每个元素都与集合B中所有元素比较一下 */
{
int i=0; /* 标记作用 */
p=head2; /* 每次都要从表头开始遍历链表,p集合B的表头 */
while(p!=NULL) /* 内循环遍历集合B,找出两个集合公共部分元素 */
{
if(pr->data==p->data)
{
i=1;
break;
}
p=p->next;
}
if(i==0)
{
temp=(struct Set*)malloc(sizeof(struct Set));
temp->data=pr->data;
temp->next=NULL;
head=Sort(head,temp); /*以集合B为基础,找出集合A中独有的元素,调用排序函数*/
}
pr=pr->next;
}
return head;
}
/***函数功能:求集合A和集合B的对称差E***************************************************/
struct Set* DCC(struct Set * head1 , struct Set * head2)
{
struct Set *a=NULL, *b=NULL;
a=JiaoJi(head1, head2); /* 求交集 */
b=BingJi(head1, head2); /* 求并集 */
while(a != NULL)
{
b=DeleteNode(b,a->data); /* 调用删除节点函数 */
a=a->next;
}
return b;
}
/***函数功能:删除节点函数**************************************************************/
struct Set* DeleteNode(struct Set* head, int data)
{
struct Set *p=head, *pr=head;
while(data != p->data)
{
pr = p;
p = p->next;
}
if(p==head)
head = p->next;
else
pr->next = p->next;
free(p); /* 释放已删除节点分配的内存 */
return head;
}
/***函数功能:释放内存空间**************************************************************/
void DeleteAll(struct Set* head)
{
struct Set* pr=NULL;
while(head!=NULL)
{
pr=head->next;
free(head); /* 释放已申请的内存空间 */
head=pr;
}
}