繁体   English   中英

C程序-链接列表中的链接列表

[英]C program - linked list inside linked list

假设我想创建一本书的清单,这些书有一个或多个作者,以及书中的主要人物。 为此创建结构的最佳方法是什么? 以下内容是否准确或设置不同?

struct name
{
char prefix[5];
char first[50];
char middle[50];
char last[50];
char suffix[5];
struct name *next; /* linked list   */
struct name *previous; /* linked list   */
};


struct book
{
 struct name authors;  
 struct name main_characters;
char title[100];   
char publisher[100]; 

结构书 结构书*上一个;

};

我认为您的计划很好,使用authorsmain_characters指针。 当您在使用书籍,作者和主要人物的侵入式链表时,发现链表的结构和操作可能会有所帮助。

如果您声明这样的结构:

struct node
{
    struct node *next;
    struct node *previous;
};
typedef struct node node;

您可以将其作为第一个元素嵌入到每种类型中:

struct name
{
    node linked_list;
    char name_prefix[10];
    char name_first[50];
    char name_middle[50];
    char name_last[50];
    char name_suffix[5];
};

struct book
{
    node linked_list;
    name *authors;  
    name *main_characters;

    /* variables for book */
    char title[100];   /* the title of the book */
    char publisher[100]; /* publisher */
    //etc.
};

这使您的类型可转换为node类型 然后,您可以根据node类型定义链表操作:

void 
node_add_node(node **head, node *object)
{
    if (*head == NULL) {
        *head = object;
    }
    else {
        node *current, *previous;
        for (current = *head; current != NULL; current = current->next) {
            previous = current;
        }
        previous->next = object;
    }
}

然后定义类型安全的操作,以将书籍添加到书籍列表中并为书籍添加名称:

void 
books_add_book(struct book **books, struct book *book)
{
    node_add_node((node**)books, (node*)book);
}

void
book_add_author(struct book *book, struct name *author)
{
    node_add_node((node**)&book->authors, (node*)author);
}

void
book_add_main_character(struct book *book, struct name *character)
{
    node_add_node((node**)&book->main_characters, (node*)character);
}

然后,实现构造函数:

void node_init(node *node)
{
    node->previous = NULL;
    node->next = NULL;
}

struct book *
book_create(const char *title, const char *publisher)
{
    struct book *b = malloc(sizeof(book));
    if (b) {
        node_init(&b->linked_list);
        b->authors = NULL;
        b->main_characters = NULL;
        strcpy(b->title, title);
        strcpy(b->publisher, publisher);
    }
    return b;
}

struct name *
name_create(const char *prefix, const char *first, const char *middle, 
    const char *last, const char *suffix)
{
    name *n = malloc(sizeof(name));
    if (n) {
        node_init(&n->linked_list);
        strcpy(n->name_prefix, prefix);
        strcpy(n->name_first, first);
        strcpy(n->name_middle, middle);
        strcpy(n->name_last, last);
        strcpy(n->name_suffix, suffix);
    }
    return n;
}

然后,您可以创建像这样的书( 注意 :我将您的name_prefix的大小增加到10):

 struct book *books = NULL;
 struct book *b = book_create("War and Peace", "Wordsworth");
 struct name *n = name_create("Count", "Lev", "Nikolayevich", "Tolstoy", "");
 book_add_author(b, n);
 n = name_create("Count", "Pyotr", "Kirillovich", "Bezukhov", "");
 book_add_main_character(b, n);
 n = name_create("Countess", "Natalya", "Ilyinichna", "Rostova", "");
 book_add_main_character(b, n);
 books_add_book(&books, b);

为此创建结构的最佳方法是什么?

最好的方法取决于问题的细节,并且在某种程度上是见解。

以下内容是否准确或设置不同?

您介绍的两个选择看起来都很合理。

第一种选择是将两个名称struct本身作为book struct成员,这在某些情况下可能会更加方便,因为它需要较少的动态分配。 另一方面,它使每个内部链接列表的第一个元素成为特殊情况,这可能会使您的代码整体上更加复杂。

第二种选择是,书struct包含指向两个名称struct s的指针,这使您更具一致性,并且更好地容纳了一个或两个内部列表为空的可能性。 考虑到所有事情,这就是我可能会考虑的事情。

在大多数情况下,您需要的数据结构是根据您拥有的数据类型以及您要对其执行的操作来决定的。

链表适合以下需求:

  1. 频繁插入和删除数据
  2. 数据量可能不适合一个地方/或无法立即使用。

它带有以下问题:

  1. 搜索和检索数据速度慢
  2. 在您的代码中增加更多的复杂性和间接性。

据我所知,字符串的动态数组(char数组)足以满足authors或者如果您担心粒度问题,则可以使用指向struct name的指针数组,因为一本书可能有多位作者。

如果您想要静态数组,可以为您做以下工作:

#define MAX_AUTHOR_LIMIT 10
struct boook {
    ...
    struct name *authors[MAX_AUTHOR_LIMIT];
    int author_count;
    ...
}

或者,如果您想变得更好,也可以使用动态数组。

链接列表也是一种替代方法,但是对于不需要频繁插入删除操作的小型数据项使用链接不是一个好主意,但是正如我指出的那样,您知道应用程序需要根据交易。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM