user-0 提问: 合并线性表

回复:
user: user-1
content: 引用 23 楼 u012514377 的回复:这个样子的逆置和输出是不是就是带头结点的类型？ 这个样子是了  不过，这是C++语言（用到引用）写的C链表（1.没有分开链表和节点的概念,2.没有用到类）  而且，不是标准形式（C标准的链表,会把 链表 typedef 为指针,一般数据结构的书上，都是这么做的）  不知道该OJ的标准是啥，刷题的时候，最好看看OJ，有何标准。  不同平台的标准，可能不一样，C,C++代码要求可能不一样。 其他，可能包括代码的时间复杂度（很多算法题在3S以内），和空间复杂度要求等等。

user: user-0
content: 恩 已经AC了，  题目要求的是实现不带头结点的链表→_→，但是题目没有说，TMD····   void printlist_single(list *&L)//has been done { 	list *p; 	p=L; 	while(p->next!=NULL) 	{ 		p=p->next; 		printf("%d",p->D); 		if(p->next==NULL) 			printf(" "); 	} }  void mergelist(list *&L,list *&Q,list *&head) { 	init_single(head); 	list *p,*q; 	p=L->next; 	q=Q->next; 	while(p!=NULL || q!=NULL) 	{ 		if(p->D>=q->D) 		{ 			head->next=p; 			p=p->next; 		} 		else if(p->D<q->D) 		{ 			head->next=q; 			q=q->next; 		} 		head=head->next; 	} 	while(p!=NULL) 	{ 		head->next=p; 		p=p->next; 		head=head->next; 	} 	while(q!=NULL) 	{ 		head->next=q; 		q=q->next; 		head=head->next; 	} 	head->next=NULL;  }     我就不另开贴了~~~~  还是那个合并线性表，  在有头结点的实现情况下，  这样写问题出在哪里了咩？

user: user-0
content: 这个样子的逆置和输出是不是就是带头结点的类型？

user: user-0
content: void init_single(list *&L)//has been done { 	L=(list*)malloc(sizeof(list)); 	L->next=NULL; }  void creatlist_single(list *&L,int n)//has been done { 	list *s,*r; 	init_single(L); 	r=L; 	int i=1; 	while(i<=n) 	{ 		s=(list*)malloc(sizeof(list)); 		if(scanf("%c",&s->D) && (s->D!=' ')) 		{ 			r->next=s; 			r=r->next;//use plus to position to position 			i++; 		} 		else 			free(s); 	} 	r->next=NULL; }  void printlist_single(list *&L)//has been done { 	list *p; 	p=L; 	while(p->next!=NULL) 	{ 		p=p->next; 		printf("%c",p->D); 		if(p->next!=NULL) 			printf(" "); 	} }  list* reverseList(list *&L)   {   	list *p1,*p2; 	if(L==NULL || L->next==NULL) 		return L; 	p1=L->next; 	L->next=NULL; 	while(p1!=NULL) 	{ 		p2=p1;; 		p1=p1->next; 		p2->next=L->next; 		L->next=p2; 	} 	return L; }         咳 改成这样了，可是OJ还是没过，OJ上没说要不要有头结点

user: user-0
content: void printlist_single(list *&L)//has been done { 	list *p; 	p=L; 	while(p->next!=NULL) 	{ 		printf("%c",p->D); 		p=p->next; 		if(p->next!=NULL) 			printf(" "); 	} }  list* reverseList(list *&L)   {   	list *p1,*p2,*p3; 	if(L==NULL || L->next==NULL) 		return L; 	p1=L; 	p2=L->next; 	while(p2!=NULL) 	{ 		p3=p2->next;//存后一个节点 		p2->next=p1;//翻转 		p1=p2;//p1记录当前节点 		p2=p3;//p2向后一个位置 	} 	L->next=NULL; 	L=p1; 	return L; }         带空节点的输出函数是怎么样的？请问我这样改可以不？

user: user-2
content: 有点混乱，init里看到是带空头节点，print和reverse却是不带。貌似把接口重新改写定好来，除了init，free传引用，其它参数最好是不用引用，避免误操作，合并嘛2个参数就好，和并到第一个表里...

user: user-1
content: 1)void mergelist(list *&L,list *&Q,list *head) 合并链表的参数错误,写成这样才行 void mergelist(const list *L,const list *Q,list *&Dst) 2)你这个反转链表和创建操作不符合,  创建的是带空的头节点的链表, 原因是init_single创建了空的头节点  反转的时候,当成了不带空的头节点的链表反转  输出,也是按照,不带空的头节点的链表输出的  结果是,你自己的程序调试的时候,结果是正确的. OJ 测试的时候,不正确. 原因是,算法错误. 这是我个人的看法  PS: 带空的头节点的链表,输出的时候,不需要输出头结点 OJ测试算法的时候,不是用你的输出算法,所以你自己测试貌似正确,OJ测试错误  ----你自己输出了,不需要输出的头结点, OJ测试的时候,不会输出头结点,因为这个节点,不存储数据. 所以你的程序中,输出的头结点数据,是错误的数据,不是链表的第一个数据. 原因是,你没有正确实现,反转算法  先看清楚,OJ要求实现的, 是带空的头节点的链表, 还是带空的头节点的链表, 再写代码

user: user-0
content: na  引用 9 楼 lm_whales 的回复:基本上还是可以的,不过对单链表本身的类型,了解的不是很好  混淆了带空的头节点的链表,和不带空的头节点的链表. 这两种链表的数据是一样的,不同的是有没有,多加一个空的(无数据的)节点.  不过你这里,企图通过修改输出函数,   而不是数据结构的核心算法,来达到结果正确的方式,是不应该出现的. 需要做正确的,是数据结构的算法,  包括建表,插入,删除,销毁,查找,以及反转. 可能的话,还包括遍历.  输出链表,其实就是一种遍历算法,哪有不输出最后一个数据的..  一般顺序表(包括各种链表),不讲遍历,因为比较简单. 树等比较复杂的数据结构,才考虑遍历算法.  那个是因为这个朋友说我第一个节点是空节点，不用翻转，所以把它跳过去了！  实际运行也是木有问题的！

user: user-1
content: L=L->next;头结点丢失

user: user-0
content: void printlist_single(list *&L)//has been done {     list *p;     p=L;     while(p!=NULL)     {         printf("%c",p->D);         p=p->next;         if(p!=NULL)             printf(" ");     } }   Printlist原来是这样的，提交也不对，我就改成L，还是不对。 我觉得所有的节点都连上了，实际上自己VC上的输出也是对的，  可是OJ判断上 YOUR OUTPUT 少输出了翻转后第一个节点的内容，  我十分不解呐！！！

user: user-1
content: 1) #14  printlist_single 错误,输出结束后,所有节点丢失,因为传递的是指针引用,可以修改指针参数的值  2)合并算法,   大有这么几种,   2.1)排序,非破坏合并,目标跟源不同;   这种就是创建新的链表,所有两个链表中的数据,按大小先后插入新的链表   方法是比较两个链表,当前结点的数据大小,大(或者小)的数据插入新链表(需要分配内存),然后继续...   2.2)排序,破坏合并,目标跟源不同      方法同上,每次比较两个链表,头结点的数据大小,大(或者小)的节点插入新链表,不用分配内存    2.3)不用排序,非破坏合并,目标跟源不同,合并只是复制数据.;      依次复制两个链表的数据直接插入新的链表   2.4)不用排序,破坏合并,目标跟一个源相同,两个合并成一个,所有节点合并到一起,另一个成为空链表.      两个链表首尾相接成一个链表   2.5)不用排序,非破坏合并(半破坏),目标跟一个源相同,合并只是复制数据.       直接在尾部插入另一个链表的数据

user: user-0
content: void creatlist_single(list *&L,int n)//has been done { 	list *s,*r; 	init_single(L); 	r=L; 	int i=1; 	while(i<=n) 	{ 		s=(list*)malloc(sizeof(list)); 		if(scanf("%c",&s->D) && (s->D!=' ')) 		{ 			r->next=s; 			r=r->next;//use plus to position to position 			i++; 		} 		else 			free(s); 	} 	r->next=NULL; }  void printlist_single(list *&L)//has been done { 	while(L!=NULL) 	{ 		printf("%c",L->D); 		L=L->next; 		if(L!=NULL) 			printf(" "); 	} }  list* reverseList(list *&L)   {       //让p1和p2都指向第一个结点       list *p1=NULL;       list *p2=NULL; 	L=L->next;     while(L!=NULL) //p1存后一个节点，p2存当前节点      {           p1=L->next;//存后一个节点         L->next=p2;//后一个节点指向前一个节点         p2=L;//p2作为表头 依次储存L         L=p1;//L向后遍历一个节点     }       return p2; }     根据楼上的楼上的建议，我改成这样了，感觉节点接上了啊，自己输出的时候也没错，可是还是不行啊，另外 不是最后一个节点没有输出，是第一个节点没输出，我自己VC上是对的。  OJ给的提示是：  INPUT 10 1 2 3 4 5 6 7 8 9 a  YOUR OUTPUT 9 8 7 6 5 4 3 2 1 OUR INPUT a 9 8 7 6 5 4 3 2 1  可是我自己VC上是对的！！！

user: user-0
content: 合并不需要排序，就取上一个元素下一个元素这样反复取啊，但是为什么ABAB这样也不行捏？

user: user-3
content: 你合并的时候怎么没有考虑head所指节点数值的大小啊，怎么能ABAB这样呢，有可能是ABBA什么的。。

user: user-3
content: 你合并的时候怎么没有考虑head所指节点数值的大小啊，怎么能ABAB这样呢，有可能是ABBA什么的。。

user: user-0
content: 您说的是第二个吧？我懂了，但是第一个合并线性表的问题出在哪里啊？

user: user-1
content: 基本上还是可以的,不过对单链表本身的类型,了解的不是很好  混淆了带空的头节点的链表,和不带空的头节点的链表. 这两种链表的数据是一样的,不同的是有没有,多加一个空的(无数据的)节点.  不过你这里,企图通过修改输出函数,  而不是数据结构的核心算法,来达到结果正确的方式,是不应该出现的. 需要做正确的,是数据结构的算法,  包括建表,插入,删除,销毁,查找,以及反转. 可能的话,还包括遍历.  输出链表,其实就是一种遍历算法,哪有不输出最后一个数据的..  一般顺序表(包括各种链表),不讲遍历,因为比较简单. 树等比较复杂的数据结构,才考虑遍历算法.

user: user-1
content: 1)printlist_single 错误,少输出一个节点. 2)reverselist 错误,你这个创建的是,带空头节点的链表. 所以头节点不用翻转.

user: user-0
content: 怒顶！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！

user: user-0
content: 还是不太懂，可以说一下我的代码为什么运行不成的原因不？  我是愣没看出来QAQ