【问题标题】:Link list add,delete and print imlementation链表添加、删除和打印实现
【发布时间】:2016-10-29 13:52:00
【问题描述】:

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

#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;
        }
    }
}

有什么建议吗?

【问题讨论】:

  • 奥拉夫以光速移动。
  • 这是 C++,而不是 C。但是您使用 C 编码 style,这在 C++ 中是一种不好的做法,特别适用于这个应用程序。
  • 所以。如何解决问题?
  • 崩溃使调试变得容易。在调试器中运行几乎可以肯定随您的开发环境附带的程序,并在调试器因崩溃而停止时检查程序状态。如果您无法从中找出问题所在,请将状态添加到问题中。
  • 阅读How to Ask 并关注它。正如@user4581301 所写:使用调试器了解更多信息。还要正确地格式化和缩进你的代码。

标签: c++ list linked-list


【解决方案1】:

已经指出了答案,但是...我对您的代码状态感到非常不满意,所以请允许我给您一些提示。

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


让我们从基础开始,到 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 &lt;cassert&gt;


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

只有两个挑剔:

  • 如果您知道不会再执行任何操作,请立即返回,不要等待
  • 不要使用endl,它会追加行尾并立即刷新缓冲区,这往往会导致性能问题
//  Prints the list, in order.
void print(Node* head) {
    if (head == nullptr) {
        std::cout << "empty list\n";
        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"
                 " - print\n"
                 " - quit\n";

    Node* head = nullptr;

    while (1) {
        std::cout << "> ";

        std::string op;
        if (!(std::cin >> op)) {
            std::cerr << "An error occurred reading the operation, sorry\n";
            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 ;)
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 1970-01-01
      • 2012-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多