user-0 提问: 用单链表实现两个集合的交并

回复:
user: user-1
content: 引用 8 楼 hzy_76 的回复:创建的过程中已经剔除了重复，所以这里的假定是输入链表本身是合法的，要求也并没有涉及链表纠错。  [quote=引用 7 楼 cfjtaishan 的回复:] [quote=引用 5 楼 hzy_76 的回复:] 没错，所以有这句：  if (!IsContain1(List1, node->data))  即先把List1复制一遍，然后对于List2的每个节点，判断是否存在于List1中，不存在才开始复制 我的意思是，本身List1中就有重复的，你把List1中的先拷贝到并集里，然后再拿List1和List2比较是否相同，所以还是没有解决，List1中或LIst2中有重复的时，如何去掉重复，因此先要将List1和List2去重。[/quote][/quote] 哈哈，严谨

user: user-2
content: 创建的过程中已经剔除了重复，所以这里的假定是输入链表本身是合法的，要求也并没有涉及链表纠错。  引用 7 楼 cfjtaishan 的回复:[quote=引用 5 楼 hzy_76 的回复:] 没错，所以有这句：  if (!IsContain1(List1, node->data))  即先把List1复制一遍，然后对于List2的每个节点，判断是否存在于List1中，不存在才开始复制 我的意思是，本身List1中就有重复的，你把List1中的先拷贝到并集里，然后再拿List1和List2比较是否相同，所以还是没有解决，List1中或LIst2中有重复的时，如何去掉重复，因此先要将List1和List2去重。[/quote]

user: user-1
content: 引用 5 楼 hzy_76 的回复:没错，所以有这句：  if (!IsContain1(List1, node->data))  即先把List1复制一遍，然后对于List2的每个节点，判断是否存在于List1中，不存在才开始复制 我的意思是，本身List1中就有重复的，你把List1中的先拷贝到并集里，然后再拿List1和List2比较是否相同，所以还是没有解决，List1中或LIst2中有重复的时，如何去掉重复，因此先要将List1和List2去重。

user: user-2
content: 重新帮你改写了创建、交集、并集函数如下，请参考：   SeqList* CreateSeqList(char n) { 	SeqList *Head = NULL, *Tail = NULL; 	SeqList* node = NULL; 	char ch;  	printf("输入集合%c的元素：\n", n); 	do 	{  		scanf("%c", &ch); 		if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))) 		{ 			if (!IsContain1(Head, ch)) 			{ 				node = (SeqList *) malloc(sizeof(SeqList)); 				if (node == NULL) 					return Head; 				node->data = ch; 				node->next = NULL; 				if (Tail != NULL) 				{ 					Tail->next = node; 					Tail = node; 				} 				else 				{ 					Head = Tail = node; 				} 			} 		} 	} 	while (ch != '$');  	return Head; }  //求交集 SeqList *Intersection(SeqList *List1, SeqList *List2) { 	SeqList *node1 = NULL, *node2 = NULL, *node = NULL; 	SeqList *Head = NULL, *Tail = NULL;  	node1 = List1; 	while (node1) 	{ 		if (IsContain1(List2, node1->data)) 		{ 			node = (SeqList *) malloc(sizeof(SeqList)); 			if (node == NULL) 				return Head; 			node->data = node1->data; 			node->next = NULL; 			if (Tail != NULL) 			{ 				Tail->next = node; 				Tail = node; 			} 			else 			{ 				Head = Tail = node; 			} 		} 		node1 = node1->next; 	}  	return Head; }  //求并集 SeqList *Union(SeqList *List1, SeqList *List2) { 	SeqList *Head = NULL, *Tail = NULL, *node = NULL, *tmp_node = NULL;  	node = List1; 	while (node) 	{ 		tmp_node = (SeqList *) malloc(sizeof(SeqList)); 		if (tmp_node == NULL) 			return Head; 		tmp_node->data = node->data; 		tmp_node->next = NULL; 		if (Tail != NULL) 		{ 			Tail->next = tmp_node; 			Tail = tmp_node; 		} 		else 		{ 			Head = Tail = tmp_node; 		}  		node = node->next; 	}  	node = List2; 	while (node) 	{ 		if (!IsContain1(List1, node->data)) 		{ 			tmp_node = (SeqList *) malloc(sizeof(SeqList)); 			if (tmp_node == NULL) 				return Head; 			tmp_node->data = node->data; 			tmp_node->next = NULL; 			if (Tail != NULL) 			{ 				Tail->next = tmp_node; 				Tail = tmp_node; 			} 			else 			{ 				Head = Tail = tmp_node; 			} 		}  		node = node->next; 	} 	 	return Head; }

user: user-2
content: 你搞得太复杂了，不需要一个无用的头结点，也不需要一个数据为$的尾节点，这是作为输入结束来用的。 CreateSeqList函数这么写就好了，创建出来的链表每个节点都有用。   SeqList* CreateSeqList(char n) { 	SeqList *Head = NULL, *Tail = NULL; 	SeqList* node = NULL; 	char ch;  	printf("输入集合%c的元素：\n", n); 	do 	{  		scanf("%c", &ch); 		if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))) 		{ 			if (!IsContain1(Head, ch)) 			{ 				node = (SeqList *) malloc(sizeof(SeqList)); 				if (node == NULL) 					return; 				node->data = ch; 				node->next = NULL; 				if (Tail != NULL) 				{ 					Tail->next = node; 					Tail = node; 				} 				else 				{ 					Head = Tail = node; 				} 			} 		} 	} 	while (ch != '$');  	return Head; }

user: user-1
content: //#include "targetver.h" //#include"HeadFile.h" #include <stdio.h> //#include <tchar.h> #include<stdlib.h>  /*******HeadFile.h***/ typedef struct Node {     char data;     Node* next; }SeqList;  bool IsContain(SeqList List, int x); bool IsContain1(SeqList* List, char x); SeqList* Intersection(SeqList* List1, SeqList* List2); SeqList* Union(SeqList* List1, SeqList* List2); SeqList* CreateSeqList(char n); void Print(SeqList* List);   //判断一个元素是否包含于一个集合 bool IsContain(SeqList* List, char x) {     SeqList* p = List->next;     while (p)     {         if (p->data == x)             return true;         p = p->next;     }     return false; } //用于判断一个元素是否包含于一个不用头结点表示的集合 bool IsContain1(SeqList* List, char x) {     SeqList* p = List;     while (p != NULL)     {         if (p->data == x)             return true;         p = p->next;     }     return false; } //求交集 SeqList* Intersection(SeqList* List1, SeqList* List2) {     SeqList* Seq,*Node,*r;     SeqList* p = List1->next;     Seq = (SeqList*)malloc(sizeof(SeqList));     r = Seq;     while (p != NULL)     {         if (IsContain(List2, p->data))         {             Node = (SeqList*)malloc(sizeof(SeqList));             Node->data = p->data;             r->next = Node;             r = r->next;         }         p = p->next;   /*向后遍历*/     }     return Seq; } //求并集 SeqList* Union(SeqList* List1, SeqList* List2) {     SeqList* Seq = (SeqList*)malloc(sizeof(SeqList));     SeqList* p = List1->next;     SeqList* q = List2->next;     SeqList* r = Seq;     while (p != NULL)     {         SeqList* node = (SeqList*)malloc(sizeof(SeqList));         node->data = p->data;         r->next = node;         r = r->next;         p = p->next;     }     while (q != NULL)     {         if (!IsContain(List1, q->data))         {             SeqList* node = (SeqList*)malloc(sizeof(SeqList));             node->data = q->data;             r->next = node;             r = r->next;         }         q = q->next;     }     return Seq; } //创建一个集合 SeqList* CreateSeqList(char n) {     SeqList* Seq = (SeqList*)malloc(sizeof(SeqList));     SeqList* Head = (SeqList*)malloc(sizeof(SeqList));     Seq->data = '$';     Seq->next = NULL;     // SeqList* p,*q;     //p = Seq;     //q = Seq;     printf("输入集合%c的元素：\n", n);     char ch;     do     {         scanf("%c", &ch);     } while (!((ch >= 'a'&& ch <= 'z') || (ch >= '0'&&ch <= '9')) && ch != '$');     while(ch!='$')     {         // q = Seq;         if (IsContain1(Seq, ch))         {             do{                 scanf("%c", &ch);             } while (!((ch >= 'a'&&ch <= 'z') || (ch >= '0'&&ch <= '9')));         }         else         {             SeqList* node = (SeqList*)malloc(sizeof(SeqList));             node->data = ch;             node->next = Seq;             Seq = node;             do{                 scanf("%c", &ch);             } while (!((ch >= 'a'&&ch <= 'z') || (ch >= '0'&&ch <= '9')) && ch != '$');         }     }     Head->next = Seq;     return Head; } //输出集合 void Print(SeqList* List) {     SeqList* p = List->next;     printf("(");     while (p->next!= NULL)     {         printf("%c,", p->data);         p = p->next;     }     printf("%c", p->data);     printf(")");     printf("\n"); }  /******Main.cpp***/  int main() {     SeqList* sq1, *sq2;     char cname1, cname2;     printf("输入第一个集合的名字:\n");     scanf("%c", &cname1);     getchar();     sq1 = CreateSeqList(cname1);     getchar();     printf("输入第二个集合的名字:\n");     scanf("%c", &cname2);     getchar();     sq2 = CreateSeqList(cname2);     printf("集合%c：\n", cname1);     Print(sq1);     printf("集合%c：\n", cname2);     Print(sq2);      printf("交集\n");     Print(Intersection(sq1, sq2));     printf("并集\n");     Print(Union(sq1, sq2));     return 0; } 求交集时，由于IsContain函数里没有对p执行p = p->next;很容易导致系统死机。建议注意下； 上面的代码是修改后的，参考一下吧；

user: user-0
content: 还是创建集合函数的问题，输入的判断太繁琐了，而且在主函数调用时，在输完第一个集合元素时，就跳过了第二个元素名的输入，其实是在输完第一个集合的元素时按下的回车被存储在缓冲区，当执行到输入第二个集合名的getchar()时被当做集合名了。

user: user-2
content: 没错，所以有这句：  if (!IsContain1(List1, node->data))  即先把List1复制一遍，然后对于List2的每个节点，判断是否存在于List1中，不存在才开始复制

user: user-1
content: 引用 3 楼 hzy_76 的回复:重新帮你改写了创建、交集、并集函数如下，请参考：   SeqList* CreateSeqList(char n) { 	SeqList *Head = NULL, *Tail = NULL; 	SeqList* node = NULL; 	char ch;  	printf("输入集合%c的元素：\n", n); 	do 	{  		scanf("%c", &ch); 		if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))) 		{ 			if (!IsContain1(Head, ch)) 			{ 				node = (SeqList *) malloc(sizeof(SeqList)); 				if (node == NULL) 					return Head; 				node->data = ch; 				node->next = NULL; 				if (Tail != NULL) 				{ 					Tail->next = node; 					Tail = node; 				} 				else 				{ 					Head = Tail = node; 				} 			} 		} 	} 	while (ch != '$');  	return Head; }  //求交集 SeqList *Intersection(SeqList *List1, SeqList *List2) { 	SeqList *node1 = NULL, *node2 = NULL, *node = NULL; 	SeqList *Head = NULL, *Tail = NULL;  	node1 = List1; 	while (node1) 	{ 		if (IsContain1(List2, node1->data)) 		{ 			node = (SeqList *) malloc(sizeof(SeqList)); 			if (node == NULL) 				return Head; 			node->data = node1->data; 			node->next = NULL; 			if (Tail != NULL) 			{ 				Tail->next = node; 				Tail = node; 			} 			else 			{ 				Head = Tail = node; 			} 		} 		node1 = node1->next; 	}  	return Head; }  //求并集 SeqList *Union(SeqList *List1, SeqList *List2) { 	SeqList *Head = NULL, *Tail = NULL, *node = NULL, *tmp_node = NULL;  	node = List1; 	while (node) 	{ 		tmp_node = (SeqList *) malloc(sizeof(SeqList)); 		if (tmp_node == NULL) 			return Head; 		tmp_node->data = node->data; 		tmp_node->next = NULL; 		if (Tail != NULL) 		{ 			Tail->next = tmp_node; 			Tail = tmp_node; 		} 		else 		{ 			Head = Tail = tmp_node; 		}  		node = node->next; 	}  	node = List2; 	while (node) 	{ 		if (!IsContain1(List1, node->data)) 		{ 			tmp_node = (SeqList *) malloc(sizeof(SeqList)); 			if (tmp_node == NULL) 				return Head; 			tmp_node->data = node->data; 			tmp_node->next = NULL; 			if (Tail != NULL) 			{ 				Tail->next = tmp_node; 				Tail = tmp_node; 			} 			else 			{ 				Head = Tail = tmp_node; 			} 		}  		node = node->next; 	} 	 	return Head; }  求并集时，若链表1或链表2中有重复的，那么求出并集就会有重复的；所以，是不是需要考虑重复的问题；