如何用这个结构作为数据创建一个链表?
Posted
技术标签:
【中文标题】如何用这个结构作为数据创建一个链表?【英文标题】:how to create a linked list with this struct as data? 【发布时间】:2020-12-18 03:43:57 【问题描述】:我正在尝试打印一个表格,即元素周期表中的前十个元素作为链表,其中结构体作为数据。该结构保存元素的数据,如下所示:
typedef struct element
char *name;
char *symbol;
float weight;
element;
然后像这样创建列表本身:
typedef struct list
struct element elements[]; //an array holding element types?
struct list *next;
list;
所以因为我需要打印出前 10 个元素,所以我尝试使用数组来声明名称、符号和权重,但我无法连接在链表中使用哪种方式作为数据:
char *names[10] = "Hydrogen", "Helium", "Lithium", "Beryllium", "Boron", "Carbon", "Nitrogen", "Oxygen", "Fluorine", "Neon";
char *symbols[10] = "H","He","Li","Be","B","C","N","O","F","Ne";
float weights[10] = 1.008,4.003,6.941,9.012,10.811,12.011,14.007,15.999,18.998,20.180;
【问题讨论】:
【参考方案1】:链表有一个元素数组是不常见的,尽管在某些情况下它可能很有用。在您的情况下,我认为每个列表元素都有一个元素的链表更合适:
typedef struct list
struct element element;
struct list *next;
list;
作为一种风格问题,我们最终将名称 element
用于结构名称,作为 typedef 的名称和结构成员。我建议将它们重命名为struct ELEMENT
和tElement
。与列表结构相同。这将使它像:
typedef struct ELEMENT
char *name;
char *symbol;
float weight;
tElement;
typedef struct LIST
tElement element;
struct LIST *next;
tList;
我留给你开发创建和添加到列表以及打印它的功能。
【讨论】:
【参考方案2】:只需将指针添加到下一个元素。你不需要一个新的结构。这是一些示例代码(仅添加到列表和打印实现)
有一些代码从数组中填充列表。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct element
char *name;
char *symbol;
float weight;
struct element *next;
element;
element *addToList(element *head, const char *name, const char *symbol, float weight)
element *current, tmp;
if(!head)
head = realloc(head, sizeof(*head));
current = head;
else
element *wrk;
current = head;
while(current -> next) current = current ->next;
wrk = malloc(sizeof(*head));
if(wrk)
current -> next = wrk;
current = wrk;
if(current)
current -> name = malloc(strlen(name) + 1);
current -> symbol = malloc(strlen(symbol) + 1);
//add memory checks here
strcpy(current -> name, name);
strcpy(current -> symbol, symbol);
current -> weight = weight;
current -> next = NULL;
return head;
size_t printLinst(const element *head)
size_t nelems = 0;
while(head)
printf("%zu element = \"%s\", \"%s\", %f\n", ++nelems, head -> name, head -> symbol, head -> weight);
head = head -> next;
return nelems;
/* another list functions */
char *names[10] = "Hydrogen", "Helium", "Lithium", "Beryllium", "Boron", "Carbon", "Nitrogen", "Oxygen", "Fluorine", "Neon";
char *symbols[10] = "H","He","Li","Be","B","C","N","O","F","Ne";
float weights[10] = 1.008,4.003,6.941,9.012,10.811,12.011,14.007,15.999,18.998,20.180;
#define ARRSIZE(arr) (sizeof((arr))/sizeof((arr)[0]))
int main(void)
element *head = NULL;
for(size_t index = 0; index < ARRSIZE(weights); index++)
head = addToList(head, names[index], symbols[index], weights[index]);
printf("List is %zu elements long\n", printLinst(head));
/* another code */
https://godbolt.org/z/ddEzTx
【讨论】:
非常感谢!您的代码使我理解了代码,并且也大致列出了代码【参考方案3】:链表结构有两个主要选项:
项目包含链接,因此它们本身就构成了链表节点:
struct element
char *name;
char *symbol;
float weight;
struct element *next; // <--- here
;
列表节点和数据是分开的(-ish)。例如:
struct element
char *name;
char *symbol;
float weight;
;
struct node
struct element *element; // points to the item
struct node *next;
;
或许
struct node
struct element element; // contains the item
struct node *next;
;
列表本身可以有一个单独的结构,但不是必须的。列表的最小表示只是一个指向头节点的指针:
struct node *head;
按照您的建议,通常不存在直接包含节点的结构,因为要求从这样的池中提取节点会限制列表的最大大小。有一个结构类型表示整个列表很有用还有其他原因,但这可能比您当前任务需要担心的复杂性要高。
顺便说一句,您是否要为您的结构类型声明 typedef
别名是一个完全独立的问题。我自己很少这样做。这在很大程度上是一个风格问题,但我提出它是因为有些人错误地认为typedef
是定义结构类型的必要元素。
【讨论】:
以上是关于如何用这个结构作为数据创建一个链表?的主要内容,如果未能解决你的问题,请参考以下文章