所以,我正在尝试实现一个复制构造函数,在实例化对象时,我可以选择从头到尾(正常)或尾到头(反向)复制列表。现在,当我使用复制构造函数时,它总是从头到尾复制,即使它进入反向条件也是如此。
这是我的头文件:
#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
};
这是我的复制构造函数。
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
此外,如果您需要查看它是如何附加到列表的,这里是 append() 函数。
void List::append(Student *newStudent) {
Node *newNode = new Node(newStudent); // new Node containing student arg.
newNode->getData(); // get data of student arg.
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 {
if(forward) { // append to tail of list.
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.
} else { // append to head of list.
head->setPrev(newNode); // PREV ptr of head points to newNode.
newNode->setNext(head); // newNode's NEXT points to former head.
head = newNode; // newNode becomes the new head.
} // end if/else
} // end if/else
numNodes++;
}
最佳答案
你似乎总是从头到尾复制的原因是你的代码是乱七八糟的,并且试图同时以不止一种方式做同样的事情。如果你试图从尾部复制从头到尾,您将新列表从尾部写到头部,您从尾部到头部读取旧列表。这两者相互抵消。想一想。
如果您尝试使参数 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*/
而且它有效。如果我们选择第二个,我们就不用管构造函数并更改 append(...)
:
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
一般来说,避免此类问题的方法是从小而简单开始,一次增加一点点复杂性,每一步都进行测试,首先隔离测试新功能,永远不要添加不起作用的代码.找到不明显的错误的方法是对你的代码进行简化,逐步消除复杂性,直到你达到仍然表现出错误行为的最简单版本——或者更有可能的是,错误在这个过程中变得很明显.
关于c++ - 双链表复制构造函数(不能尾对头复制),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18263818/