【问题标题】:How do I create a new Node in a Doubly Linked List? (C++)如何在双向链表中创建新节点? (C++)
【发布时间】:2017-01-06 17:42:57
【问题描述】:

我将首先提出问题,然后包含所有代码。我正在学习数据结构课程,我们提供了一个 make 文件,但我的 C++ 技能充其量只是平庸。我已经翻阅了许多不同的文章,但我仍然不知道如何集成代码以创建新节点......我必须能够创建新节点才能将它们入队、出队和执行其他操作对它们的操作与双向链表有关。

我尝试了许多不同的方法来构建构造函数,但似乎总是存在某种类型的编译器错误。

我不允许更改主文件中的任何代码,但我的所有工作都必须包含在模板化的头文件中。有人可以告诉我如何正确地做到这一点吗?我现在将包含相关代码。

这是我的头文件。我的目标是让 LinkedList 类中的 buildNode() 函数创建一个节点,然后我可以将节点添加到双向链表中。

#include <limits>
#include <string>
#include <cassert>
#include <iostream>

template <typename T>
class Node {
public:
    T data;
    Node* next;
    Node* prev;

    Node();

    ~Node();

    void getData() {

    }
};

template <typename T>
class Iterator {
private:

public:

Iterator() {
}

int operator*() const {
}

Iterator& operator++() {
}

bool operator==(Iterator const& rhs) {
}

bool operator!=(Iterator const& rhs) {
}
};

template <typename T>
class LinkedList {
private:
    Node<T> *head = 0;
    Node<T> *tail = 0;

public:

LinkedList() {
}

~LinkedList() {}

Iterator<T> begin() const {
}

Iterator<T> end() const {
}

bool isEmpty() const {
    if (this->head == 0) {
        std::cout << "Isempty works.";
        return true;
    }
}

T getFront() const {
}

T getBack() const {
}

void enqueue (T element) {
}

void dequeue() {
}

void pop() {
}

void clear() {
}

bool contains(int element) const {
}

void remove(int element) {
}

void buildNode() {  //experimental function.
    Node<T> n;
    // Node n = new Node();
    // Node<T> n;
    //Node<T> *n = new Node<T>();
    //Node n = new Node<T>;
}
};

我将只包含对这个特定挑战很重要的主文件元素,即

int main()
{
    // Get ready.
    LinkedList<string&> referenceList;
    LinkedList<char const*> valueList;

    //ascribe valueList and referenceList to a variable inside the LinkedList class...

unsigned int numOfStrings = 8;
string testStrings[] = {
        "alpha"
        , "bravo"
        , "charlie"
        , "charlie"
        , "dog"
        , "echo"
        , "foxtrot"
        , "golf"
};

string tempStr;

// Test isEmpty function.
 assert(valueList.isEmpty() && referenceList.isEmpty());

referenceList.buildNode(); //can't get this to work. Later the methodology will be transported to enqueue method.

编辑:当我使用

Node<T> * n = new Node<T>; 

在 buildNode() 函数中,我得到一个链接器错误说明:

/Applications/CLion.app/Contents/bin/cmake/bin/cmake --build /Users/Boisselle/Library/Caches/CLion2016.2/cmake/generated/LinkedList-75be2cc8/75be2cc8/Debug --target LinkedList -- -j 8
Scanning dependencies of target LinkedList
[ 50%] Building CXX object CMakeFiles/LinkedList.dir/main.cpp.o
[100%] Linking CXX executable LinkedList
Undefined symbols for architecture x86_64:
  "Node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>::Node()", referenced from:
  LinkedList<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>::buildNode() in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [LinkedList] Error 1
make[2]: *** [CMakeFiles/LinkedList.dir/all] Error 2
make[1]: *** [CMakeFiles/LinkedList.dir/rule] Error 2
make: *** [LinkedList] Error 2

【问题讨论】:

标签: c++ doubly-linked-list


【解决方案1】:

我相信您正在寻找这种语法:

Node<T> * node_pointer = new Node<T>;

模板类型应伴随数据类型名称。

【讨论】:

  • 谢谢...当我使用它创建节点时,我收到编译器错误:生成 3 个警告。 [100%] 链接 CXX 可执行 LinkedList 架构 x86_64 的未定义符号:“Node<:__1::basic_string std::__1::char_traits>, std::__1::allocator >& >::Node()”,引用自:LinkedList<:__1::basic_string std::__1::char_traits>, std::__1::allocator >&>::buildNode main.cpp.o ld 中的 ():未找到体系结构 x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
  • @Starcrossed:Thomas 的代码是对的,你的某些编译设置一定是配置错误。由于您没有向我们显示实际的错误消息,因此任何人都无法帮助您。
  • @Starcrossed:这不是编译器错误,而是链接错误。这意味着您编写了原型,向编译器承诺某些函数将存在,然后您从未编写函数体。您现在可以使用空主体 {} 作为 Node() 构造函数来绕过它,就像几乎所有其他函数一样。
  • 谢谢 Ben,我已将完整的错误消息作为对原始帖子的编辑包含在内。
【解决方案2】:

template <typename T>
class Node {
public:
    T data;
    Node* next;
    Node* prev;

    Node();

    ~Node();

    void getData() {

    }
};

Node(); 表示构造函数存在于某处,但未在此处定义。你需要完全实现这个功能和~Node();。顺便说一句,the Rule of Zero 建议您根本没有~Node();

Node() 
{ 
    do stuff here 
} 

很常见,但在你的情况下

Node() : next(nullptr), prev(nullptr) 
{ 
    /* does nothing */ 
} 

会更好一些。详情请见Member Initializer List

一旦您正确实现了Node();,您就可以按照

的建议创建一个新节点
Node<T> *n = new Node<T>();

附录:

next(nullptr)prev(nullptr) 将链接指向 null,这是未使用指针的安全停车空间。这使得测试节点以查看它所链接的内容比让它们未初始化要容易得多。使用

在构造函数中初始化 data 可能是最简单的
Node(T newdata) : data(newdata), next(nullptr), prev(nullptr) 
{ 
    /* does nothing */ 
} 

【讨论】:

  • 谢谢!我现在已经成功构建了一个节点!我刚才要弄清楚如何在构造函数中初始化类型为 T 的数据字段...!
  • 一千谢谢user4581301!这解决了我一段时间以来的主要语法问题。 !
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 2011-03-12
  • 2022-06-17
  • 1970-01-01
  • 2012-08-22
  • 2016-07-18
相关资源
最近更新 更多