C++ 合并两个已排序的列表为什么只处理第一个列表C++;
我编写了关于合并两个排序列表的代码。但是,只有head1运行,而不是head2。例如,head1:0 2 5 7 head2:0 5 8 9。输出将为0 2 5 7。谁能告诉我为什么C++ 合并两个已排序的列表为什么只处理第一个列表C++;,c++,linked-list,C++,Linked List,我编写了关于合并两个排序列表的代码。但是,只有head1运行,而不是head2。例如,head1:0 2 5 7 head2:0 5 8 9。输出将为0 2 5 7。谁能告诉我为什么 #include <iostream> using namespace std; // class node class node { private: double num; node *link; public:
#include <iostream>
using namespace std;
// class node
class node {
private:
double num;
node *link;
public:
node() { }
node(double m, node *n) { num = m; link = n; }
node* getlink() { return link; }
double getdata() { return num; }
void setdata(double m) { num = m; }
void setlink(node* n) { link = n; }
};
typedef node* nodeptr;
void insertnode(nodeptr& head, double m);
void printlist(nodeptr head);
nodeptr mergelists(nodeptr& head1, nodeptr& head2);
void reverselist(nodeptr& head);
nodeptr search(nodeptr head, double searchterm);
void insert(nodeptr afterme, double newdata);
int main()
{
double input;
nodeptr head1 = NULL; // Pointer to the head of List #1
nodeptr head2 = NULL; // Pointer to the head of List #2
nodeptr temp;
// Part 1 - Create two sorted lists
cout << "-------------------------------------" << endl;
cout << "CREATE LIST #1: " << endl;
cout << "-------------------------------------" << endl;
do {
cout << "Enter value (0 to quit): ";
cin >> input;
// Insert the "input" value into the list
insertnode(head1, input);
} while (input != 0);
cout << "-------------------------------------" << endl;
cout << "CREATE LIST #2: " << endl;
cout << "-------------------------------------" << endl;
do {
cout << "Enter value (0 to quit): ";
cin >> input;
// Insert the "input" value into the list
insertnode(head2, input);
} while (input != 0);
// Part 1 - Print the lists to make sure that they are correct.
printlist(head1);
printlist(head2);
// Part 2 - Merge the two lists and display the new merged list
cout << "Merge lists: " << endl;
temp = mergelists(head1, head2);
printlist(temp);
// Part 3 - Reverse the merged list and then display it
return 0;
}
nodeptr search(nodeptr head, double searchterm)
{
nodeptr p = head;
nodeptr q = head->getlink();
if (p == NULL)
return NULL;
else
{
while (p != NULL)
{
q = p->getlink();
while (q != NULL && q->getdata() < searchterm)
{
p = p->getlink();
q = q->getlink();
}
return p;
}
}
}
void insertnode(nodeptr& head, double m)
{
// CASE 1 - List is empty
if (head == NULL)
{
head = new node(m, NULL);
}
// CASE 2 - List is not empty and new value is < 1st value
else if (m < head->getdata())
{
head = new node(m, head);
}
// CASE 3 - List is not empty and new value goes inside list
else
{
// search for correct location - notes on Search
nodeptr afterme = search(head,m);
// insert at this location -- see notes on insert inside list
nodeptr temp;
temp = new node(m, afterme->getlink());
afterme->setlink(temp);
}
}
void printlist(nodeptr head)
{
nodeptr p;
p = head;
while (p != NULL)
{
cout << p->getdata() << endl;
p = p->getlink();
}
}
// mergelist function -> wrong result
nodeptr mergelists(nodeptr& head1, nodeptr& head2)
{
if (head1 == NULL)
return head2;
if (head2 == NULL)
return head1;
nodeptr result = new node(0, NULL);
nodeptr head = result;
while (head1 != NULL&&head2 != NULL){
if (head1->getdata() <head2->getdata()){
result ->getlink() = head1;
head1 = head1 -> getlink();
}
else{
result->getlink() = head2;
head2 = head2->getlink();
}
result = result ->getlink();
}
if (head1 == NULL){
result ->getlink() = head2;
}
else{
result ->getlink() = head1;
}
return head->getlink();
}
#包括
使用名称空间std;
//类节点
类节点{
私人:
双数;
节点*链接;
公众:
节点(){}
node(双m,node*n){num=m;link=n;}
node*getlink(){return link;}
double getdata(){return num;}
void setdata(双m){num=m;}
void setlink(node*n){link=n;}
};
typedef节点*nodeptr;
void insertnode(nodeptr和head,双m);
无效打印列表(nodeptr head);
nodeptr合并列表(nodeptr&head1、nodeptr&head2);
无效反向列表(nodeptr和head);
nodeptr搜索(nodeptr头,双搜索项);
无效插入(nodeptr afterme,double newdata);
int main()
{
双输入;
nodeptr head1=NULL;//指向列表#1的头的指针
nodeptr head2=NULL;//指向列表#2的头的指针
nodeptr温度;
//第1部分-创建两个排序列表
coutgetlink();
}
否则{
结果->getlink()=head2;
head2=head2->getlink();
}
结果=结果->获取链接();
}
if(head1==NULL){
结果->getlink()=head2;
}
否则{
结果->getlink()=head1;
}
返回head->getlink();
}
以下是我的输出:
帮助阅读,让您了解一些术语:如果您已经知道这些术语的含义,请跳过链接。如果你在继续之前没有阅读它,那么你将得到的不仅仅是这个答案中的“如何修复错误”部分 当您从函数返回一个值时,您可以保证得到的只是一个临时的copy1。所以这里 返回指向
节点的指针,但指针本身是指针的副本。它不是链接
,它是链接的临时副本,只存在足够长的时间将其分配给其他内容。使用上面链接的术语,这是一个右值。所以在
result ->getlink() = head1;
head1
将被分配给link
的临时副本,该副本仅在执行分配所需的时间内存在
从分配数据到一个只存在几纳秒的拷贝中,你得到的不是很多,所以定义C++工作原理的大脑袋决定,这样做应该是错误的,这是程序不能工作的原因。结果是您收到的错误消息。不能分配给右值,但可以分配给左值
那么如何将右值转换为左值呢
最简单的方法是不返回临时副本。最简单的方法是返回指针的引用
node* & getlink() { return link; }
现在,您不再返回链接的副本,而是返回。。。这取决于编译器。您可能会得到链接
。您可能会得到指向链接的指针。如果编译器认为您无法注意到(),您可能会得到zelda
。编译器可能会将整个函数剥离出来,并替换为极其简单的函数,如link=head1
只有当您深入到编译器设计或性能调优的本质时,真正发生的事情才有意义。但是编译器认为适合这样做
result ->getlink() = head1;
现在可以通过返回函数调用将head1
分配给link
这是一种魔法,它允许您在std::vector
中设置一个值,并且vec[99]=11代码>或自定义矩阵
类,具有mat(3,2)=7代码>
以上仅解释了错误消息以及如何修复它。它没有声明程序的逻辑是否正确
1与引用的工作方式一样,编译器在这里有很大的回旋余地,如果要复制的对象很大或很难复制,编译器会做一些非常鬼鬼祟祟的工作,将该副本转换为计算强度较低的副本。如果您感兴趣,请查看复制省略和RVO的多种风格。您的合并列表()
代码既不创建新节点来表示已排序的列表,也不使用setlink()
来更改指针指向的位置。@KenY-N所以我更改了代码。但结果有一个错误:表达式必须是可修改的左值。我怎样才能修好它?谢谢你,你对推荐人有多熟悉?你需要返回一个指向指针的引用来拉动这个技巧,我想你是在尝试,我对它不是很熟悉。这是否像对已经存在的变量使用另一个名称一样?你能给我一个具体的例子吗(我的代码-太好了)。对于C++,我真的很新。它起作用了。我还有一个新的解决方案:将result->getlink()=head1更改为result->setlink(head1)@dandelion适合我。智者曾说:“调整有用的东西,拒绝无用的东西,增加你自己的东西。”
result ->getlink() = head1;