关于C++单链表实现的问题
question about C++ single linked list implementation
我正在研究下面的代码,但是对函数read_file()中的单链表的构建感到困惑,我在下面代码旁边的函数处标记了问题:
完整代码如下:https://github.com/mickyjm/c.cpp.address.book.project/tree/master/CPP
列出头文件list.h
#ifndef LLIST_H
#define LLIST_H
#include <string>
class llist {
private:
record *start;
std::string file_name;
int read_file();
int write_file();
record* reverse_llist(record *);
void delete_all_records();
public:
llist();
llist(std::string);
~llist();
int add_record(std::string, std::string, int, std::string);
int print_record(std::string);
int modify_record(std::string, std::string, std::string);
void print_all_records();
int delete_record(std::string);
void reverse_llist();
};
#endif
记录头文件record.h
#include <string>
#ifndef RECORD_H
#define RECORD_H
struct record {
std::string name;
std::string address;
int birth_year;
std::string phone_number;
struct record* next;
};
#endif
list.cppread_file函数
int llist::read_file() {
// read_file variables
std::ifstream read_file(file_name.c_str());
struct record *temp = NULL;
struct record *index = NULL;
struct record *previous = NULL;
int file_char_length = 0;
int record_count = 0;
std::string dummy = "";
if (!read_file.is_open()) {
read_file.close();
return -1;
} // end if !read_file.is_open()
read_file.seekg(0, read_file.end); // move read pointer to end of file
file_char_length = read_file.tellg(); // return file pointer position
if (file_char_length == 0) {
read_file.close();
return 0;
} // end file_char_length == 0
read_file.seekg(0, read_file.beg); // reset file pointer to beginning
do { // do while !read_file.eof()
// do while temporary variables
std::string address = "";
temp = new record;
index = start;
std::getline(read_file, temp->name);
std::getline(read_file, temp->address, '$');
read_file >> temp->birth_year;
std::getline(read_file, dummy);
std::getline(read_file, temp->phone_number);
std::getline(read_file, dummy);
++record_count;
while (index != NULL) { <-- what's the purpose of this loop?
previous = index;
index = index->next;
} // end while index != NULL
if (previous == NULL) { <-- why would the start pointer of the
temp->next = start; list not at the start but after temp?
start = temp;
} else { // else if previous != NULL
previous->next = temp; <-- what is the purpose of this loop?
temp->next = index;
} // end if previous == NULL
} while (!read_file.eof()); // end do while
read_file.close();
return record_count; // read_file return - end of function
}
按提问顺序排列。
- 这个循环的目的是什么?
while (index != NULL) {
previous = index;
index = index->next;
} // end while index != NULL
答案:这个循环用于将previous
定位到列表中的最后一个节点上,只要至少有一个节点即可。有多种技术可以做到这一点;这是比较常见的一种。当 index
跑到循环的尽头时 previous
落后一步。
- 为什么链表的起始指针不在开头而是在temp之后?
if (previous == NULL) {
temp->next = start;
start = temp;
答案:与该问题的语法作斗争,这里使用 start
作为此作业的 right-side 是没有意义的。它必须是 NULL,否则之前的循环会加载 previous
和 non-NULL 值,而这个 if-condition 会失败。代码可以很容易地阅读:temp->next = nullptr; start = temp;
- 这个循环的目的是什么?
} else { // else if previous != NULL
previous->next = temp;
temp->next = index;
} // end if previous == NULL
答:首先,这不是循环。这是之前 if
的 else
子句,这意味着如果它运行是因为 previous
是 non-null。类似于上面(2)中 start
的奇怪用法,这里使用 index
是没有意义的。如果您查看在 (1) 中询问的循环,您会清楚地看到直到 index
为 NULL 才会停止。那里和这里之间没有什么能改变这个事实。因此,temp->next = nullptr;
等价于这里发生的事情。
不是粉饰它;这个实现很薄弱,而且是在美好的一天。无论它来自谁,都可以将其视为可以如何完成的集合,但绝不是应该如何完成的集合。
我正在研究下面的代码,但是对函数read_file()中的单链表的构建感到困惑,我在下面代码旁边的函数处标记了问题:
完整代码如下:https://github.com/mickyjm/c.cpp.address.book.project/tree/master/CPP
列出头文件list.h
#ifndef LLIST_H
#define LLIST_H
#include <string>
class llist {
private:
record *start;
std::string file_name;
int read_file();
int write_file();
record* reverse_llist(record *);
void delete_all_records();
public:
llist();
llist(std::string);
~llist();
int add_record(std::string, std::string, int, std::string);
int print_record(std::string);
int modify_record(std::string, std::string, std::string);
void print_all_records();
int delete_record(std::string);
void reverse_llist();
};
#endif
记录头文件record.h
#include <string>
#ifndef RECORD_H
#define RECORD_H
struct record {
std::string name;
std::string address;
int birth_year;
std::string phone_number;
struct record* next;
};
#endif
list.cppread_file函数
int llist::read_file() {
// read_file variables
std::ifstream read_file(file_name.c_str());
struct record *temp = NULL;
struct record *index = NULL;
struct record *previous = NULL;
int file_char_length = 0;
int record_count = 0;
std::string dummy = "";
if (!read_file.is_open()) {
read_file.close();
return -1;
} // end if !read_file.is_open()
read_file.seekg(0, read_file.end); // move read pointer to end of file
file_char_length = read_file.tellg(); // return file pointer position
if (file_char_length == 0) {
read_file.close();
return 0;
} // end file_char_length == 0
read_file.seekg(0, read_file.beg); // reset file pointer to beginning
do { // do while !read_file.eof()
// do while temporary variables
std::string address = "";
temp = new record;
index = start;
std::getline(read_file, temp->name);
std::getline(read_file, temp->address, '$');
read_file >> temp->birth_year;
std::getline(read_file, dummy);
std::getline(read_file, temp->phone_number);
std::getline(read_file, dummy);
++record_count;
while (index != NULL) { <-- what's the purpose of this loop?
previous = index;
index = index->next;
} // end while index != NULL
if (previous == NULL) { <-- why would the start pointer of the
temp->next = start; list not at the start but after temp?
start = temp;
} else { // else if previous != NULL
previous->next = temp; <-- what is the purpose of this loop?
temp->next = index;
} // end if previous == NULL
} while (!read_file.eof()); // end do while
read_file.close();
return record_count; // read_file return - end of function
}
按提问顺序排列。
- 这个循环的目的是什么?
while (index != NULL) {
previous = index;
index = index->next;
} // end while index != NULL
答案:这个循环用于将previous
定位到列表中的最后一个节点上,只要至少有一个节点即可。有多种技术可以做到这一点;这是比较常见的一种。当 index
跑到循环的尽头时 previous
落后一步。
- 为什么链表的起始指针不在开头而是在temp之后?
if (previous == NULL) {
temp->next = start;
start = temp;
答案:与该问题的语法作斗争,这里使用 start
作为此作业的 right-side 是没有意义的。它必须是 NULL,否则之前的循环会加载 previous
和 non-NULL 值,而这个 if-condition 会失败。代码可以很容易地阅读:temp->next = nullptr; start = temp;
- 这个循环的目的是什么?
} else { // else if previous != NULL
previous->next = temp;
temp->next = index;
} // end if previous == NULL
答:首先,这不是循环。这是之前 if
的 else
子句,这意味着如果它运行是因为 previous
是 non-null。类似于上面(2)中 start
的奇怪用法,这里使用 index
是没有意义的。如果您查看在 (1) 中询问的循环,您会清楚地看到直到 index
为 NULL 才会停止。那里和这里之间没有什么能改变这个事实。因此,temp->next = nullptr;
等价于这里发生的事情。
不是粉饰它;这个实现很薄弱,而且是在美好的一天。无论它来自谁,都可以将其视为可以如何完成的集合,但绝不是应该如何完成的集合。