关于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
}

按提问顺序排列。

  1. 这个循环的目的是什么?
while (index != NULL) { 
    previous = index;                      
    index = index->next;
} // end while index != NULL

答案:这个循环用于将previous定位到列表中的最后一个节点上,只要至少有一个节点即可。有多种技术可以做到这一点;这是比较常见的一种。当 index 跑到循环的尽头时 previous 落后一步。

  1. 为什么链表的起始指针不在开头而是在temp之后?
if (previous == NULL) { 
    temp->next = start;                 
    start = temp;

答案:与该问题的语法作斗争,这里使用 start 作为此作业的 right-side 是没有意义的。它必须是 NULL,否则之前的循环会加载 previous 和 non-NULL 值,而这个 if-condition 会失败。代码可以很容易地阅读:temp->next = nullptr; start = temp;

  1. 这个循环的目的是什么?
} else { // else if previous != NULL    
    previous->next = temp;
    temp->next = index;
} // end if previous == NULL 

答:首先,这不是循环。这是之前 ifelse 子句,这意味着如果它运行是因为 previous 是 non-null。类似于上面(2)中 start 的奇怪用法,这里使用 index 是没有意义的。如果您查看在 (1) 中询问的循环,您会清楚地看到直到 index 为 NULL 才会停止。那里和这里之间没有什么能改变这个事实。因此,temp->next = nullptr; 等价于这里发生的事情。

不是粉饰它;这个实现很薄弱,而且是在美好的一天。无论它来自谁,都可以将其视为可以如何完成的集合,但绝不是应该如何完成的集合。