在线等待,急!两个单链表有序合并,为什么输不出c链

luckylau 2003-10-10 12:56:27
#include "iostream.h"

typedef struct student
{
long number;
float score;
student * next;
}student, *linklist;

void crea(linklist & head,int n)
{
student * ps,* pEnd;
int i;
if((head=new student)==NULL)
{ cout<<"ERROR!"<<endl; return; }
cout<<"enter students' number and score!"<<endl;
cin>>head->number>>head->score;
pEnd=head;
for(i=1;i<n;i++)
{
if((ps=new student)==NULL)
{ cout<<"ERROR!"<<endl; return; }
cout<<"enter students' number and score!"<<endl;
cin>>ps->number>>ps->score;
pEnd->next=ps;
pEnd=ps;
}
pEnd->next=NULL;
}


void showlist(linklist & l,int num)
{
int i;
for(i=0;i<num;i++)
{
cout<<" number : "<<l->number<<" "<<" score : "<<l->score<<endl;
l=l->next;
}

}


void unionlist(linklist & la,linklist & lb,linklist & lc)
{
student *pa,*pb,*q;

pa=la;
pb=lb;
lc=la;
q=lc;
while(pa&&pb)
{
if(pa->number<=pb->number)
{ q->next=pa;
pa=pa->next;
q=pa; }
else
{ q->next=pb;
pb=pb->next;
q=pb; }

}
q=pa?pa:pb;

}


void main()
{

int numa,numb;
linklist A,B,C;

cout<<"input total students in class A!"<<endl;
cin>>numa;
crea(A,numa);
cout<<" class A"<<endl;
cout<<endl;
showlist(A,numa);

cout<<"input total students in class B!"<<endl;
cin>>numb;
crea(B,numb);
cout<<" class B"<<endl;
cout<<endl;
showlist(B,numb);


unionlist(A,B,C);
showlist(C,numa+numb);

}
...全文
335 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
mfcer2 2003-10-11
  • 打赏
  • 举报
回复
/*
* 楼主,你的题好像没有说清楚。请问链表A和B的初始条件是什么,
* 是无序的还是有序的。如果是有序的,是非递增还是非递减;还有,
* A与B合并成C之后,C应为非递增还是非递减。
*
* 但我跟据你程序中的意思,推测出: 你所说的"两个链表有序合并"
* 是否指A,B在合并之前应是按每个链表中结点的number域进行非递
* 减排列的.然后合并的结果C也同样按number域非递减排列的.
*
* 这里,我首先假设A,B跟据每个结点的number域非递减排列(一个简单
* 的情况,这意味着在输入时,关键值——在你的程序中为number域,
* 要按非递减顺序输入),并将你的程序改了一点.
*------------------------------------------------------------
* 实现环境: Dev-C++ 4.9.8.0
*/

#include <iostream.h>

typedef struct student
{
long number;
float score;
student *next;
} student, *linklist;

void crea(linklist &head, int n)
{
student *ps, *pEnd;

if((head = new student) == NULL)
{
cout << "ERROR!" << endl;
return;
}
cout << "enter students' number and score!" << endl;
cin >> head->number >> head->score;
pEnd = head;
for(int i = 1; i < n; i++)
{
if((ps = new student) == NULL)
{
cout << "ERROR!" << endl;
return;
}
cout << "enter students' number and score!" << endl;
cin >> ps->number >> ps->score;
pEnd->next = ps;
pEnd = ps;
}
pEnd->next=NULL;
}

// 你在这个函数中犯了一个错!!!
// 这也是你什么不能输出合并后的链表的原因!
void showlist(/* linklist &l */ linklist &L, int num)
{ // 不要用小写的l,这易与数字1混淆
/*
for(i = 0;i < num; i++)
{
cout << " number : " << l->number << " "
<< " score : " << l->score << endl;
// 在这个函数里l为linklist &的引用,那么在这个函数
// 里对l进行的改动便是改动了"调用函数"中的实参数的值
l = l->next;
}
*/
// 这里才是对的!
// 定义一个局部变量p,在下面的循环块中对p进行的
// 改变不会改动调用函数中的实参数的值。
linklist p = L;

for (int i = 0; i < num; i++)
{
cout << " number : " << p->number << " "
<< " score : " << p->score << endl;
p = p->next;
}
}

void unionlist(linklist &la, linklist &lb, linklist &lc)
{
linklist pc, // pc指向lc的尾部
q; // q指向A或B中临时删去的那个关键值较小的结点

// 在这里la, lb也是linklist的一个引用,当la,lb改变时,
// 调用函数中的实参的值也变了,但这没有关系!因为la,lb是.
// 要删除的.但lc只能指向合并后链表的头一个结点,因为你还
// 要在打印时,用到它.lc不能改变
while (la && lb)
{
if (la->number <= lb->number)
{
q = la;
la = la->next;
}
else
{
q = lb;
lb = lb->next;
}

if (!lc) // 对应main中的C = NULL想想
lc = pc = q;
else
{
pc->next = q;
pc = q;
}
}
if (la)
q->next = la;
if (lb)
q->next = lb;
/*******************************************************
student *pa, *pb, *q,
pa = la;
pb = lb;
lc = la;
q = lc;
// 这个while语句块有问题!我在上面重写了一个。
while(pa && pb)
{
if(pa->number <= pb->number)
{
q->next = pa;
pa = pa->next;
q = pa;
}
else
{
q->next = pb;
pb = pb->next;
q = pb;
}
}
q = pa ? pa : pb; // 你这里玩了点技巧,但不是很成功!
// 可以这样玩:q->next = la ? la : (lb ? lb : NULL);
// 但这是一种不太好的编程习惯!要强调可读性.
********************************************************/
}

/*
* 这个函数是我自己加上去的,当程序完成之后,一定要把链表占用
* 的资源回收!
*/
void deletelist(linklist &head)
{
linklist delNode;

while (head)
{
delNode = head;
head = head->next;
delete delNode;
}
}

int main(void)
{
int numa, numb;
linklist A, B, C = NULL;

cout << "input total students in class A!" << endl;
cin >> numa;
crea(A, numa);
cout << "\n class A\n" << endl;
showlist(A, numa);

cout << "input total students in class B!" << endl;
cin >> numb;
crea(B, numb);
cout << "\n class B\n" << endl;
showlist(B, numb);

unionlist(A, B, C);
cout << "\n class C\n" << endl;
showlist(C, numa + numb);
deletelist(C); // 程序完成后要删去结点,归还资源!!!

return 0;
}
短歌如风 2003-10-10
  • 打赏
  • 举报
回复
此外上述的实现代码中A发生了变化,需要先把它的头节点保存起来(可以直接放到lc中)。
短歌如风 2003-10-10
  • 打赏
  • 举报
回复
q->next=pa有可能会影响以后pb->next的取值,而q->next = pb也会影响以后pa->next的取值。

其实链表有序合并很简单:
有链表A,B:
if A = nil then
A := B
B := nil
elif B <> nil and Value(A[0]) > Value(B[0]) then
Swap(A, B)
endif

while B <> nil Loop
 在A中找到大于B的第一个节点(假设升序);将此节点开始的序列从A中断开成为链表C。
把B链到A末尾。
B := C;
endloop

最后A中就是结果。

主要代码(循环部分)写出来就是:

while (B)
{
while (A->next && A->next->number <= B->number)
A = A -> next;
C = A ->next;
A -> next = B;
B = C;
}
你的链表是有头节点的,所以循环之前的初始化更简单:
A不会为空。
头节点不参与比较
所以直接进入循环可能就可以了。不过这时B不能是头节点(A = la, B = lb->next)。具体实现你自己试一下。
pantherzz 2003-10-10
  • 打赏
  • 举报
回复
typedef struct student
{
long number;
float score;
STRUCT student * next;//在这里漏了STRUCT
}student, *linklist;
luckylau 2003-10-10
  • 打赏
  • 举报
回复
我是要合并链表,不是删除相同项
darcymei 2003-10-10
  • 打赏
  • 举报
回复
逻辑混乱了
if(pa->number<=pb->number)
{ q->next=pa;
pa=pa->next;
q=pa; }
else
{ q->next=pb;
pb=pb->next;
q=pb; }
想一下q指向pa后,next又指向pb,使得此点pa的next也指向pb然后....
http://expert.csdn.net/Expert/topic/2322/2323000.xml?temp=.4145471
这里有我写的一个方法,参考下巴

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧