下面的代码正确插入节点但是 我有一个问题,当试图打印列表时,程序不幸停止工作。 错误消息是:您的项目已停止工作。 这是我的代码:
#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;
}
}
}
有什么建议吗?
答案 0 :(得分:3)
答案被指出,但是...我对你的代码状态感到非常不满意,所以请允许我给你一些提示。
注意:除非重点是构建列表,否则请重用现有的标准容器(特别是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 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 ;)
}
答案 1 :(得分:1)
let rec twoTwo (s : string) (n : int) : string =
match n with
|0 -> 0 // Error on this line: this expression was expected to have type string, but here has type int
|_ -> s + (twoTwo s (n-1))
永远不会设置为st::next
。这使NULL
中的p!=NULL
测试有些问题。
解决方案:当节点是尾节点时为NULL print
。