C++ 双链表复制构造函数(不能将尾部复制到头部)
因此,我试图实现一个复制构造函数,在实例化一个对象时,我可以选择从头部到尾部(正常)或从尾部到头部(反向)复制一个列表。现在,当我使用复制构造函数时,它总是从头到尾复制,即使它进入相反的条件 这是我的头文件:C++ 双链表复制构造函数(不能将尾部复制到头部),c++,copy-constructor,doubly-linked-list,C++,Copy Constructor,Doubly Linked List,因此,我试图实现一个复制构造函数,在实例化一个对象时,我可以选择从头部到尾部(正常)或从尾部到头部(反向)复制一个列表。现在,当我使用复制构造函数时,它总是从头到尾复制,即使它进入相反的条件 这是我的头文件: #include <iostream> #include "Student.h" #include "Node.h" using namespace std; class List { public: List(); // Default constructor
#include <iostream>
#include "Student.h"
#include "Node.h"
using namespace std;
class List {
public:
List(); // Default constructor
List(const List&); // Copy constructor (2-in-1, see lab sheet)
~List(); // Destructor
bool isEmpty(); // List is empty: TRUE or FALSE?
int getNumNodes() {return numNodes;} // How many Nodes in List
void append(Student *); // Append new Node to head or tail of List
void insert(Student *); // Inserts new Node in the
// Appropriate location in List
void deleteNode(string); //Search for and delete specific Node
void displayAscending();// Display List HEAD to TAIL
void displayDescending(); // Display List TAIL to HEAD
// input Student::data into Student pointer.
void input(Student*, string, string, string, string, string);
Node *getHead() const {return head;} // ptr to head.
Node *getTail() const {return tail;} //ptr to tail.
private:
void printer(Node *); //recursive function w/in displayDescending()
Node *head;
Node *tail;
bool empty;
bool forward; // forward = head-to-tail i.e. true
int numNodes; // number of nodes in the list
};
#包括
#包括“Student.h”
#包括“Node.h”
使用名称空间std;
班级名单{
公众:
List();//默认构造函数
List(const List&);//复制构造函数(二合一,见实验表)
~List();//析构函数
bool isEmpty();//列表为空:TRUE还是FALSE?
int getNumNodes(){return numNodes;}//列表中有多少个节点
void append(Student*);//将新节点追加到列表的开头或结尾
void insert(Student*);//在
//列表中的适当位置
void deleteNode(字符串);//搜索并删除特定节点
void displaysensings();//从头到尾显示列表
void displaydensing();//从尾部到头部显示列表
//将Student::数据输入到Student指针中。
无效输入(学生*,字符串,字符串,字符串,字符串,字符串,字符串);
Node*getHead()常量{return head;}//ptr to head。
Node*getTail()常量{return tail;}//ptr to tail。
私人:
void printer(Node*);//递归函数w/in displayDescending()
节点*头;
节点*尾部;
布尔空;
bool forward;//forward=从头到尾,即true
int numNodes;//列表中的节点数
};
这是我的复制构造函数
List::List(List &list) { // Copy constructor
head = NULL; // Head pointer set to NULL initially
tail = NULL; // Tail pointer set to NULL initially
empty = true;
forward = true; // Copies head-to-tail by default.
numNodes = 0;
string flag; // Stores prompt value.
cout << "Copy from head to tail? (y/n): ";
cin >> flag; // prompt for user.
if(flag == "n")
forward = false;
Node *curr = NULL; //initialize curr in function scope.
if(flag == "n") {
forward = false;
curr = list.getTail(); // curr points to list tail.
cout << "Copying in reverse order...\n" << endl;
} else { // forward == true
curr = list.getHead(); // curr points to list head.
cout << "Copying from head-to-tail...\n" << endl;
} // end if/else
while(curr) {
string f = ( curr->getData()->getFirst() );
string m = ( curr->getData()->getMid() );
string l = ( curr->getData()->getLast() );
string s = ( curr->getData()->getSocial() );
string a = ( curr->getData()->getAge() );
Node *nodePtr = NULL; // a node that's pointing
// using it to point to creation of
// a new node
Student *stuPtr = new Student; // creates a stud pointer on
// heap of Student class in
// order to store stud info
input(stuPtr,f,m,l,s,a); // input Student::data into stuPtr.
append(stuPtr); // append the node with stuPtr to head or tail
// of list.
if(!forward)
curr = curr->getPrev();
else
curr = curr->getNext();
} // end while*/
cout << "Done copying!\n" << endl;
} // end copy constructor
List::List(List&List){//复制构造函数
head=NULL;//头指针最初设置为NULL
tail=NULL;//尾部指针最初设置为NULL
空=真;
forward=true;//默认情况下从头到尾复制。
珠心=0;
字符串标志;//存储提示值。
cout>flag;//提示用户。
如果(标志==“n”)
正向=假;
Node*curr=NULL;//在函数范围内初始化curr。
如果(标志==“n”){
正向=假;
curr=list.getTail();//curr指向列表尾部。
coutgetmid());
字符串l=(curr->getData()->getLast());
字符串s=(curr->getData()->getSocial());
字符串a=(curr->getData()->getAge());
Node*nodePtr=NULL;//指向的节点
//使用它来指向
//新节点
Student*stuPtr=new Student;//在上创建一个螺柱指针
//一大堆学生在教室里上课
//订购以存储螺柱信息
输入(stuPtr,f,m,l,s,a);//将Student::data输入stuPtr。
append(stuPtr);//将带有stuPtr的节点追加到head或tail
//名单的一部分。
如果(!向前)
curr=curr->getPrev();
其他的
curr=curr->getNext();
}//结束时*/
cout setPrev(newNode);//头部的PREV ptr指向newNode。
newNode->setNext(head);//newNode的下一个指向前一个head。
head=newNode;//newNode成为新的head。
}//如果结束/else
}//如果结束/else
节点++;
}
通过使用const
参数,可以调用const对象上的非const成员函数。非const
函数不承诺不修改对象。您可以将这些成员函数声明为const
,以避免此错误:
Node *getHead() const
。。等等
关于你的第一个问题,我还不知道如何解决,我有一些建议:
- 使用
代替NULL ptr
或NULL
0
- 用于字符串:
stringf{curr->getData()->getFirst()}代码>
我建议您使用一个好的调试器工具,如VisualStudio,逐行调试代码;它将帮助你在几分钟内解决你的问题。如果您仍然不确定,您可以将要测试的代码量减少到几行,然后发布。您总是从头到尾地复制代码的原因是您的代码杂乱无章,并且试图一次以多种方式执行相同的操作。如果你试着从一个尾巴到另一个头部复制,你会从另一个尾巴到另一个头部写下新的列表,然后从另一个尾巴到另一个头部阅读旧的列表。这两者相互抵消。想想看 如果您试图使参数
const
,则会出现编译器错误的原因是您正在使用getTail()
和getHead()
对其进行查询,而您没有使用const
编辑:
让我们回到设计上来,考虑一下从尾部到头部的复制应该如何工作。基本上有两种方法,读头-尾和写尾-头:
| |
v v
A-B-C-D A
| |
v v
A-B-C-D B-A
| |
v v
A-B-C-D C-B-A
| |
v v
A-B-C-D D-C-B-A
反之亦然:
| |
v v
A-B-C-D D
| |
v v
A-B-C-D D-C
| |
v v
A-B-C-D D-C-B
| |
v v
A-B-C-D D-C-B-A
但如果我们同时尝试这两种方法,它们会抵消:
| |
v v
A-B-C-D D
| |
v v
A-B-C-D C-D
| |
v v
A-B-C-D B-C-D
| |
v v
A-B-C-D A-B-C-D
我们所要做的就是选择一个。如果我们选择第一个,我们将更改复制系数:
curr = list.getHead(); // curr points to list head.
cout << "Reading from head-to-tail...\n" << endl;
while(curr) {
...
append(stuPtr); // append the node with stuPtr to head or tail of list.
curr = curr->getNext();
} // end while*/
一般来说,避免此类问题的方法是从小处着手,一次增加一点复杂性,在每一步都进行测试,首先单独测试新特性,永远不要添加不起作用的代码。找到不明显的错误的方法是将代码简化,逐段消除复杂性,直到您得到仍然显示错误行为的最简单版本——或者更可能的是,错误在过程中变得明显。这回答了部分问题,但顶部还有另一个问题。谢谢Oleksiy!这解决了常数问题。现在剩下的就是从尾到头的复制问题。@Oleksiy:我听说过使用nullptr有一段时间了,但是我还没有GCC编译器,我相信我的教授也没有。关于列表初始化的问题,你能澄清一下你的意思吗?@baph0mt点击“列表初始化”链接-我最近发表了一篇关于itI的帖子,我可以理解你的意思,但我没有
curr = list.getHead(); // curr points to list head.
cout << "Reading from head-to-tail...\n" << endl;
while(curr) {
...
append(stuPtr); // append the node with stuPtr to head or tail of list.
curr = curr->getNext();
} // end while*/
if(isEmpty()) { // tail=NULL, no list.
cout << "List is empty. Inserting first Node.\n" << endl;
head = newNode;
tail = newNode; // new Node becomes head & tail.
} else {
tail->setNext(newNode); // NEXT ptr of tail points to newNode.
newNode->setPrev(tail); // newNode's PREV points to former tail.
tail = newNode; // newNode becomes the new tail.
} // end if/else