链接列表的添加、删除和打印实现

Link list add,delete and print imlementation

本文关键字:打印 实现 删除 列表 添加 链接      更新时间:2023-10-16

下面的代码正确插入节点,但是我有一个问题,当试图打印列表的程序不幸停止工作。错误消息是:您的项目已停止工作。这是我的代码:

#include <iostream>
#include <string>
using namespace std;
typedef struct st {
    string data;
    int ISBN;
    string Title;
    string Author;
    int publishedyear;
    bool borrow;
    st* next;
} NODE;
NODE* add(NODE* head, int isbn)
{
    NODE *p1, *p2;
    NODE* n;
    n = new NODE;
    n->ISBN = isbn;
    if (head == NULL) {
        head = n;
        return head;
    }
    if (n->ISBN < head->ISBN) {
        n->next = head;
        head = n;
        return head;
    }
    p1 = p2 = head;
    while (p2 != NULL) {
        if (n->ISBN < p2->ISBN) {
            n->next = p2;
            p1->next = n;
            return head;
        }
        else {
            p1 = p2;
            p2 = p2->next;
        }
    }
    n->next = p2;
    p1->next = n;
    return head;
}
void print(NODE* head)
{
    NODE* p;
    p = head;
    if (head == NULL) {
        cout << "empty list" << endl;
    }
    while (p != NULL) {
        cout << "Book ISBN Is : " << p->ISBN << endl;
        p = p->next;
    }
}
void main()
{
    // cout << "hi";
    NODE* head;
    head = NULL;
    string op;
    int isbn;
    cout << "Enter the opertion in the following format : op , ISBN" << endl;
    while (1) {
        cin >> op;
        if (op == "add") {
            cin >> isbn;
            if (op == "add") {
                head = add(head, isbn);
                cout << "book with thie ISBN code " << isbn << " is added successfuly."
                     << endl;
            }
        }
        else if (op == "print") {
            print(head);
        }
        else {
            cout << "Enter vaild operation! ." << endl;
        }
    }
}

有什么建议吗?

答案已经指出,但是……我对你的代码状态感到非常不满意,所以请允许我给你一些建议。

注意:除非是构建一个列表,否则重用现有的标准容器(特别是vector)和算法(sort),而不是构建自己的


让我们从基础开始,现在是2016年,你应该已经可以使用c++ 11了。

c++ 11允许在声明点直接初始化数据成员,我建议你对所有内置类型(整型、布尔型、浮点型和指针)都这样做,因为默认情况下它们会包含令人费解的垃圾。

struct Node {
    std::string data;
    int ISBN = 0;
    std::string title;
    std::string author;
    int publishedyear = 0;
    bool borrow = false;
    Node* next = nullptr;
};

请注意,这单独解决了您的错误。而且还能避免下次忘记。


其次,add方法不应该负责创建节点。这是混合关注点,并且它还使大多数节点具有默认值,并且如果不通过其ISBN查找它,就没有办法访问它。

还有一点是add方法没有考虑到的:如果ISBN已经在列表中怎么办?

// Adds the new node to the list, maintaining the ordering by ISBN.
//
// Returns the new head of the list, unless an existing node in the list already
// has this ISBN in which case returns `nullptr`.
Node* add(Node* head, Node* node) {
    assert(node != nullptr && "Null argument provided");
    if (head == nullptr) {
        return node;
    }
    if (node->ISBN < head->ISBN) {
        node->next = head;
        return node;
    }
    if (node->ISBN == head->ISBN) {
        return nullptr;
    }
    //  Find "current" such that "current->ISBN" < "node->ISBN" and
    //                           "node->ISBN" <= "current->next->ISBN"
    Node* current = head;
    while (current->next != nullptr && node->ISBN > current->next->ISBN) {
        current = current->next;
    }
    if (node->ISBN == current->next->ISBN) {
        return nullptr;
    }
    node->next = current->next;
    current->next = node;
    return head;
}

注:assert需要#include <cassert> .


你的打印方法已经很不错了,恭喜你!

有两个问题:

  • 如果你知道不会再执行任何操作,立即返回,不要等待
  • 不使用endl,它附加了行尾并立即刷新缓冲区,这通常会导致性能问题
//  Prints the list, in order.
void print(Node* head) {
    if (head == nullptr) {
        std::cout << "empty listn";
        return;
    }
    for (Node* p = head; p != nullptr; p = p->next) {
        std::cout << "Book ISBN: " << p->ISBN << "n";
    }
}

最后是修改后的main .

请注意,我对帮助文本进行了一点扩展,并提供了一个(干净的)quit操作。

然而,主要的变化是没有处理输入错误。处理输出错误留给读者作为练习(提示:让它们抛出)。

正确处理分配的内存也是一个很好的练习。

int main() {
    std::cout << "Enter one of the following operations when prompted:n"
                 " - add <isbn>n"
                 " - printn"
                 " - quitn";
    Node* head = nullptr;
    while (1) {
        std::cout << "> ";
        std::string op;
        if (!(std::cin >> op)) {
            std::cerr << "An error occurred reading the operation, sorryn";
            break;
        }
        if (op == "quit") {
            std::cout << "See you later!n";
            break;
        }
        if (op == "print") {
            print(head);
            continue;
        }
        if (op == "add") {
            int isbn = 0;
            if (!(std::cin >> isbn)) {
                std::cout << "Please provide a correct ISBN!n";
                continue;
            }
            Node* node = new Node();
            node->ISBN = isbn;
            Node* h = add(head, node);
            if (h == nullptr) {
                std::cout << "This ISBN was already provided!n";
                delete node;
                continue;
            }
            head = h;
            continue;
        }
        std::cout << "Please enter a valid operation!n";
    }
    // Deal with allocated memory ;)
}

st::next永远不会设置为NULL。这使得在print中测试p!=NULL有些问题。

解决方案:当节点为尾节点时,next为NULL