我正在写一个通用的双链表。我收到一些我不太懂的错误:
我不确定我写课程的方式是什么问题,但我无法让它发挥作用。也许这是我创建结构节点部分的方式,但在线搜索似乎这是一个非常标准的方法。
到目前为止,这是我的代码:
#ifndef DoubleLinkedLists_h
#define DoubleLinkedLists_h
template <class T>
class DoubleLinkedLists {
private:
struct Node {
T data;
T* next;
T* previous;
};
Node* head;
Node* tail;
public:
// Constructors
DoubleLinkedLists() : head(nullptr), tail(nullptr) {}
DoubleLinkedLists(DoubleLinkedLists const& value);
~DoubleLinkedLists();
// Overload operators
DoubleLinkedLists& operator=(DoubleLinkedLists const& rhs);
friend std::ostream& operator<<(std::ostream& str, DoubleLinkedLists<T>& data) {
data.display(str);
return str;
}
// Member functions
void swap(DoubleLinkedLists& other) noexcept;
void createNode(const T& theData);
void createNode(T&& theData);
void display(std::ostream& str) const;
void display() const;
void insertHead(const T& theData);
void insertTail(const T& theData);
void insertPosition(int pos, const T& theData);
void deleteHead();
void deleteTail();
void deletePosition(int pos);
bool search(const T& x);
};
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists const& value) : head(nullptr), tail(nullptr) {
for(Node* loop = value->head; loop != nullptr; loop = loop->next) {
createNode(loop->data);
}
}
template <class T>
DoubleLinkedLists<T>::~DoubleLinkedLists() {
while(head != nullptr) {
deleteHead();
}
}
template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists const& rhs) {
DoubleLinkedLists copy(rhs);
swap(copy);
}
template <class T>
void DoubleLinkedLists<T>::swap(DoubleLinkedLists<T>& other) noexcept {
using std::swap;
swap(head, other.head);
swap(tail, other.tail);
}
template <class T>
void DoubleLinkedLists<T>::createNode(const T& theData) {
Node* newNode;
Node* temp = new Node;
newNode->data = theData;
newNode->previous = nullptr;
newNode->next = nullptr;
if(head == nullptr) {
head = temp;
tail = temp;
temp = nullptr;
}
else {
newNode = head;
while(newNode != nullptr) {
newNode = newNode->next;
}
newNode->next = temp;
temp->previous = newNode;
}
}
template <class T>
void DoubleLinkedLists<T>::createNode(T&& theData) {
Node* newNode;
Node* temp = new Node;
newNode->data = std::move(theData);
newNode->next = nullptr;
if(head == nullptr) {
temp->previous = nullptr;
head = temp;
}
else {
newNode = head;
while(newNode->next != nullptr) {
newNode = newNode->next;
}
newNode->next = temp;
temp->previous = newNode;
}
}
template <class T>
void DoubleLinkedLists<T>::display(std::ostream &str) const {
for(Node* loop = head; loop != nullptr; loop = loop->next) {
str << loop->data << "\t";
}
str << "\n";
}
template <class T>
void DoubleLinkedLists<T>::display() const {
for(Node* loop = head; loop != nullptr; loop = loop->next) {
std::cout << loop->data << "\t";
}
std::cout << "\n";
}
#endif /* DoubleLinkedLists_h */
这是main.cpp文件:
#include <iostream>
#include "DoubleLinkedLists.h"
int main(int argc, const char * argv[]) {
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Double Linked List //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
DoubleLinkedLists<int> obj;
obj.createNode(2);
obj.createNode(4);
obj.createNode(6);
obj.createNode(8);
obj.createNode(10);
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"---------------Displaying All nodes---------------";
std::cout<<"\n--------------------------------------------------\n";
obj.display();
return 0;
}
修改
#ifndef DoubleLinkedLists_h
#define DoubleLinkedLists_h
template <class T>
class DoubleLinkedLists {
private:
struct Node {
T data;
Node* next;
Node* previous;
};
Node* head;
Node* tail;
public:
// Constructors
DoubleLinkedLists() : head(nullptr), tail(nullptr) {} // empty constructor
DoubleLinkedLists(DoubleLinkedLists const& value); // copy constructor
DoubleLinkedLists<T>(DoubleLinkedLists<T>&& move) noexcept; // move constuctor
DoubleLinkedLists<T>& operator=(DoubleLinkedLists&& move) noexcept; // move assignment operator
~DoubleLinkedLists(); // destructor
// Overload operators
DoubleLinkedLists& operator=(DoubleLinkedLists const& rhs);
friend std::ostream& operator<<(std::ostream& str, DoubleLinkedLists<T> const& data) {
data.display(str);
return str;
}
// Member functions
void swap(DoubleLinkedLists& other) noexcept;
void createNode(const T& theData);
void createNode(T&& theData);
void display(std::ostream& str) const;
void display() const;
void insertHead(const T& theData);
void insertTail(const T& theData);
void insertPosition(int pos, const T& theData);
void deleteHead();
void deleteTail();
void deletePosition(int pos);
bool search(const T& x);
};
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists const& value) : head(nullptr), tail(nullptr) {
for(Node* loop = value->head; loop != nullptr; loop = loop->next) {
createNode(loop->data);
}
}
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists<T>&& move) noexcept : head(nullptr), tail(nullptr) {
move.swap(*this);
}
template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists<T> &&move) noexcept {
move.swap(*this);
return *this;
}
template <class T>
DoubleLinkedLists<T>::~DoubleLinkedLists() {
while(head != nullptr) {
deleteHead();
}
}
template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists const& rhs) {
DoubleLinkedLists copy(rhs);
swap(copy);
}
template <class T>
void DoubleLinkedLists<T>::swap(DoubleLinkedLists<T>& other) noexcept {
using std::swap;
swap(head, other.head);
swap(tail, other.tail);
}
template <class T>
void DoubleLinkedLists<T>::createNode(const T& theData) {
}
template <class T>
void DoubleLinkedLists<T>::createNode(T&& theData) {
Node* newNode;
Node* temp = new Node;
temp->data = std::move(theData);
temp->next = nullptr;
if(head == nullptr) {
temp->previous = nullptr;
head = temp;
tail = temp;
}
else {
newNode = head;
newNode->previous = temp;
newNode = newNode->next;
}
}
template <class T>
void DoubleLinkedLists<T>::display(std::ostream &str) const {
for(Node* loop = head; loop != nullptr; loop = loop->next) {
str << loop->data << "\t";
}
str << "\n";
}
template <class T>
void DoubleLinkedLists<T>::display() const {
for(Node* loop = head; loop != nullptr; loop = loop->next) {
std::cout << loop->data << "\t";
}
std::cout << "\n";
}
template <class T>
void DoubleLinkedLists<T>::deleteHead() {
Node* old = head;
head = head->next;
delete old;
}
#endif /* DoubleLinkedLists_h */
答案 0 :(得分:2)
对于数据以及下一个和上一个指针,您使用T
,当指针应该是Node*
类型时,就像头部和尾部一样。
答案 1 :(得分:2)
错误是由next
previous
Node
成员声明为T*
而不是Node*
引起的。
您的代码中也存在其他一些问题。
operator<<
需要data
作为const
引用,因为display()
被声明为const
(应该是):< / p>
friend std::ostream& operator<<(std::ostream &str, DoubleLinkedLists<T> const &data)
operator=
未返回任何内容(需要返回*this
)。
此外,它没有处理自我分配的可能性。
template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists const& rhs) {
if (this != &rhs) { // <-- add this
DoubleLinkedLists copy(rhs);
swap(copy);
// alternatively:
// DoubleLinkedLists(rhs).swap(*this);
}
return *this; // <-- add this
}
没有移动构造函数或移动赋值运算符的实现。
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists && value) : head(nullptr), tail(nullptr) {
value.swap(*this);
}
template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists && rhs) {
rhs.swap(*this);
}
在createNode()
的两个版本中访问错误。
当您指向有效的newNode
实例时,您正在访问Node
的成员。
在第一次访问时,newNode
未初始化(您正在初始化temp
)。
在head
不是nullptr
时查找最后一个节点的循环是错误的,导致newNode
在您第二次访问其成员时始终最终成为nullptr
。无论如何,循环是不必要的,因为您可以(并且应该)将新节点简单地附加到tail
的右侧。
此外,createNode()
的移动版本在tail
最初head
时未将新创建的节点分配给nullptr
。
template <class T>
void DoubleLinkedLists<T>::createNode(const T& theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = nullptr;
newNode->next = nullptr;
if (!head)
head = newNode;
if (tail) {
newNode->previous = tail;
tail->next = newNode;
}
tail = newNode;
}
template <class T>
void DoubleLinkedLists<T>::createNode(T&& theData) {
Node* newNode = new Node;
newNode->data = std::move(theData);
newNode->previous = nullptr;
newNode->next = nullptr;
if (!head)
head = newNode;
if (tail) {
newNode->previous = tail;
tail->next = newNode;
}
tail = newNode;
}
或者,你可以让一个人调用另一个,这样你就不必重复两次相同的逻辑:
template <class T>
void DoubleLinkedLists<T>::createNode(const T& theData) {
T copy(theData);
createNode(std::move(copy));
}
并非真正的错误,但display()
的无参数版本可以将std::cout
传递给display()
的1参数版本,因此您无需复制相同的循环两次:
template <class T>
void DoubleLinkedLists<T>::display() const {
display(std::cin);
}