[英]Merging two sorted lists why just work on the first list C++
我編寫了有關合並兩個排序列表的代碼。 但是,僅head1運行而不是head2。 例如,head1:0 2 5 7 head2:0 5 8 9.輸出將是0 2 57。有人可以告訴我為什么嗎?
#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();
}
這是我的輸出:
有用的讀物,使您了解一些術語: 什么是右值,左值,x值,glvalue和prvalue? 如果您已經知道這些術語的含義,請跳過鏈接。 如果您在繼續之前不閱讀它,那么您將獲得的不僅僅是答案的“如何解決錯誤”部分。
當從函數中按值返回值時 ,可以保證得到的是臨時副本1 。 所以在這里
node* getlink() { return link; }
您返回一個指向node
的指針,但是指針本身是指針的副本。 它不是link
,它是link
的臨時副本,僅存在足夠長的時間才能將其分配給其他對象。 使用上面鏈接的術語,這是一個右值。 所以在
result ->getlink() = head1;
將head1
分配給link
的臨時副本,該副本僅head1
分配所需的時間內存在。
將數據分配給僅存在幾納秒的副本並不會帶來什么好處,因此,定義C ++工作方式的聰明才智決定,這樣做確實是錯誤的,以致無法理解該程序將無法工作。 結果是您收到的錯誤消息。 您不能分配給右值,但是可以分配給左值。
那么如何將右值變成左值呢?
最簡單的方法是不返回臨時副本。 最簡單的方法是返回對指針的引用
node* & getlink() { return link; }
現在,您無需返回link
的副本,而是返回...好吧,這取決於編譯器。 您可能會獲得link
。 您可能會得到指向link
的指針。 如果編譯器認為您無法注意到( 按規則 ),則可能會得到zelda
。 整個函數可能會被編譯器剝離,並替換為類似link = head1
簡單殘酷的東西。
只有當您深入了解編譯器設計或性能調整時,真正發生的事情才有意義。 但是,編譯器認為適合這樣做,
result ->getlink() = head1;
現在可以通過返回函數調用來分配head1
進行link
。
這就是讓您在vec[99] = 11;
的std::vector
設置值的魔力vec[99] = 11;
或mat(3,2) = 7;
的自定義matrix
類mat(3,2) = 7;
上面僅說明了錯誤消息及其解決方法。 它不對程序邏輯是否正確提出任何要求。
1與引用的工作方式一樣,編譯器在此處的操作還有很多余地,並且如果要復制的對象很大或很麻煩,則編譯器將執行一些偷偷摸摸的藍精靈操作,以將該副本轉換為計算量較小的對象復制。 如果您感興趣,請查閱Copy Elision和RVO的許多版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.