C++ 合并两个已排序的列表为什么只处理第一个列表C++;

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:

我编写了关于合并两个排序列表的代码。但是,只有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:
        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;