【问题标题】:Search and protecting singly linked list in C++在 C++ 中搜索和保护单链表
【发布时间】:2019-07-24 00:05:43
【问题描述】:

我有一个关于在 ints 的单链表上搜索元素的问题,在这种情况下,使用 C++。我正在创建自己的锻炼列表版本。这是代码

假设我有两个搜索功能。我知道我们需要遍历整个列表直到找到元素,因为我们没有像数组那样的直接访问权限。 这两个功能是:

bool search(int n); // Traverse the list till find n.
bool search(Node* node, int n); Traverse the list till find n only after *node (included)

1 例:我的列表有以下元素:[0, 1, 2, 3]

如果我搜索 3,我很容易在列表末尾找到。不错。

问题: 2 case:我的列表有以下元素:[0, 1, 2, 3, 3, 3, 4, 5, 6]

如果我搜索 3:

bool search(int n);

我将始终获取第一个 3 元素,除非我有对第二个或第三个 3 元素的引用以传递给该函数:

bool search(Node* node, int n);

我的问题是这是否是单链表中的正确搜索算法。这两种类型的函数或者我是否应该有其他类型。

下面是我的实际代码的代码(我没有放代码用于搜索):

SingleLinkedList.h

struct Node {
    int data;
    Node* next;

    Node(int d = 0)
        : data {d}, next {nullptr}
    {}
};

class SinglyLinkedList {
public:
    SinglyLinkedList();
    ~SinglyLinkedList();

    void display();
    bool addFirst(const int); // Add a node to the beginning of the list.
    bool addFirst(Node*); // Add a node to the beginning of the list.
    bool addLast(const int); // Add a node to the end of the list.
    bool addLast(Node*); // Add a node to the end of the list.

private:
    Node* head;
    Node* tail;
};

SinglyLinkedList.h

#include "SinglyLinkedList.h"
#include <iostream>

SinglyLinkedList::SinglyLinkedList()
    : head {nullptr}, tail {nullptr}
{}

SinglyLinkedList::~SinglyLinkedList() {
    Node* iterationNode = head;
    Node* actualNode {nullptr};

    while (iterationNode != nullptr) {
        actualNode = iterationNode;
        iterationNode = iterationNode->next;

        delete actualNode;
    }
}

void SinglyLinkedList::display() {
    std::cout << "################### Displaying Linked List ###################" << std::endl;

    if (head == nullptr) {
        std::cout << "Linked List is empty!" << std::endl;
    }
    else {
        Node* iterationNode = head;

        std::cout << "[ ";

        while (iterationNode != nullptr) {
            std::cout << iterationNode->data << " ";
            iterationNode = iterationNode->next;
        }
        iterationNode = nullptr;
        std::cout << "]" << std::endl;
    }

    std::cout << "##############################################################" << std::endl;
}

bool SinglyLinkedList::addFirst(const int n) {
    Node* element = new Node {n};

    if (head == nullptr) {
        head = element;
        tail = element;
    }
    else {
        element->next = head;
        head = element;
    }

    return true;
}

bool SinglyLinkedList::addFirst(Node* element) {
    if (head == nullptr) {
        head = element;
        tail = element;
    }
    else {
        element->next = head;
        head = element;
    }

    return true;
}

bool SinglyLinkedList::addLast(const int n) {
    Node* element = new Node {n};

    if (head == nullptr) {
        head = element;
        tail = element;
    }
    else {
        tail->next = element;
        tail = element;
    }

    return true;
}

bool SinglyLinkedList::addLast(Node* element) {
    if (head == nullptr) {
        head = element;
        tail = element;
    }
    else {
        tail->next = element;
        tail = element;
    }

    return true;
}

Program.cpp

#include <iostream>
#include "SinglyLinkedList.h"

int main() {
    {
        SinglyLinkedList list;

        list.display();
        list.addFirst(5);
        list.addFirst(4);
        list.addFirst(3);

        Node* secondNode = new Node {2};
        list.addFirst(secondNode);

        Node* firstNode = new Node {1};
        list.addFirst(firstNode);

        Node* zeroNode = new Node;
        list.addFirst(zeroNode);

        list.addLast(6);

        list.display();
    }

    system("pause");
}

另一个问题是,我怎样才能保护我的结构,以使程序的用户不会弄乱直接更改链接/引用。例如,在Program.cpp 中,任何程序员都可以简单地这样做:

secondNode->next = zeroNode

【问题讨论】:

  • 您为什么要手动执行此操作,而不是使用标准的std::liststd::find()
  • @RemyLebeau 因为我正在创建自己的链接列表版本,以便更好地理解、练习和学习。

标签: c++ algorithm search linked-list singly-linked-list


【解决方案1】:

第一个问题的答案取决于您的需求。如果您将此作为一个学习项目进行,请实施您认为合适的任何内容。您所描述的内容适合按值搜索。

在这种情况下,防止用户直接访问您的 Node 成员的最佳方法是完全抽象出 Node 类型。您可以简单地通过在源文件中声明和定义 Node 并在标头中使用 Node* 的前向声明来做到这一点。包含您的标头的用户将不会有任何关于您的节点类型的概念。

// SinglyLinkedList.h
class SinglyLinkedList {
  //...//
  struct Node* head; // head node is forward declared
  //...//
}

// SinglyLinkedList.cc
struct Node {
  //...
};

// define ll methods

如果您确实希望用户了解 Node 类型,一种解决方案是将其成员设为私有,创建公共值访问器方法,并将 Node 设为 SinglyLinkedList 类的friend

【讨论】:

    猜你喜欢
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    相关资源
    最近更新 更多