C-链表-如何分配和浏览列表
我在使用两个结构构建链表时遇到问题 节点-包含指向下一个节点的数据和指针,以及包含指向列表头的指针的列表 我只使用node结构实现了它 我已经在main函数中初始化了一个列表的结构 超过使用malloc为列表结构分配的内存 然后我为头分配了内存,头是指向第一个节点的指针 将其发送到另一个函数,在那里输入、分配、分配, 但是我很难理解如何在不改变指向头部的指针的情况下浏览列表 在im完成节点和分配后,如何获取指向 指向列表的开头 我需要复印件吗?(节点*温度) 谢谢大家C-链表-如何分配和浏览列表,c,linked-list,C,Linked List,我在使用两个结构构建链表时遇到问题 节点-包含指向下一个节点的数据和指针,以及包含指向列表头的指针的列表 我只使用node结构实现了它 我已经在main函数中初始化了一个列表的结构 超过使用malloc为列表结构分配的内存 然后我为头分配了内存,头是指向第一个节点的指针 将其发送到另一个函数,在那里输入、分配、分配, 但是我很难理解如何在不改变指向头部的指针的情况下浏览列表 在im完成节点和分配后,如何获取指向 指向列表的开头 我需要复印件吗?(节点*温度) 谢谢大家 #define _CRT_
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
typedef struct node
{
int data;
struct node *next;
}node;
typedef struct list
{
struct node *head;
}list;
void main()
{
list *list_a;
list_a = (list*)malloc(sizeof(list));
list_a->head = (node*)malloc(sizeof(node));
assignment(list_a);
}
void assignment(list *list_a)
{
int data;
printf("please enter the numbers:\n(to stop enter ""-1"")\n\n");
scanf("%d", &data);
while (data != -1)
{
list_a->head->data = data;
list_a->head->next = (node*)malloc(sizeof(node));
list_a->head = list_a->head->next;
printf("enter a number:\n");
scanf("%d", &data);
}
}
\define\u CRT\u SECURE\u NO\u警告
#包括
类型定义结构节点
{
int数据;
结构节点*下一步;
}节点;
类型定义结构列表
{
结构节点*头部;
}名单;
void main()
{
列表*列表a;
list_a=(list*)malloc(sizeof(list));
列表a->head=(节点*)malloc(节点大小);
任务(清单a);
}
无效分配(列表*列表a)
{
int数据;
printf(“请输入数字:\n(要停止输入“”-1“”)\n\n”);
scanf(“%d”和数据);
while(数据!=-1)
{
列表a->head->data=数据;
列表a->head->next=(节点*)malloc(节点大小);
列表a->head=列表a->head->next;
printf(“输入一个数字:\n”);
scanf(“%d”和数据);
}
}
但是我很难理解如何在不改变指向头部的指针的情况下浏览列表
头部本身将是指向第一个节点的指针
/** function to create list and allocates/initilizes head, set list->n = 0.
* returns new list on success, NULL otherwise.
*/
list_t *create_list (void)
{
node_t *head = NULL;
list_t *list = malloc (sizeof *list); /* allocate list */
if (!list) { /* validate/handle error */
perror ("create_list() malloc-list");
return NULL;
}
head = create_node (0); /* create the first node */
if (!head) /* validate/handle error */
return NULL;
list->head = head; /* initialize list values */
list->n = 0;
return list; /* return list */
}
完成节点和赋值后,如何使头指针指向列表的开头
使新节点指向第一个节点,然后将指向第一个节点的指针移动到指向新添加节点的头
- 重要-您缺少
,没有它,stdlib.h
就无法使用malloc
head->[data | | NULL]
第二:temp->[data | |指针指向第一个节点]->(head)[data | | NULL]
移动头部使其指向新的第一个节点
第三:head->[data | |指针指向前一个第一个节点]->[data | | NULL]
无正当理由否决投票不是懦弱的行为吗?
但是我很难理解如何在不改变指向头部的指针的情况下浏览列表
头部本身将是指向第一个节点的指针
/** function to create list and allocates/initilizes head, set list->n = 0.
* returns new list on success, NULL otherwise.
*/
list_t *create_list (void)
{
node_t *head = NULL;
list_t *list = malloc (sizeof *list); /* allocate list */
if (!list) { /* validate/handle error */
perror ("create_list() malloc-list");
return NULL;
}
head = create_node (0); /* create the first node */
if (!head) /* validate/handle error */
return NULL;
list->head = head; /* initialize list values */
list->n = 0;
return list; /* return list */
}
完成节点和赋值后,如何使头指针指向列表的开头
使新节点指向第一个节点,然后将指向第一个节点的指针移动到指向新添加节点的头
- 重要-您缺少
,没有它,stdlib.h
就无法使用malloc
head->[data | | NULL]
第二:temp->[data | |指针指向第一个节点]->(head)[data | | NULL]
移动头部使其指向新的第一个节点
第三:head->[data | |指针指向前一个第一个节点]->[data | | NULL]
在没有正当理由的情况下否决投票不是一种懦弱的行为吗?制作链接列表有很多种方法,从头脑麻木的简单的头部添加(以相反的顺序结束)到相当标准的尾部添加,在尾部迭代节点以找到结束节点,然后在那里添加新节点。在所有情况下,只需正确处理指针、分配存储(对于列表父结构和每个节点)并验证所有分配,然后自行清理并在不再需要时释放已用内存 嵌套结构中有一个包含
head
节点的结构(希望还有其他有用的数据来证明嵌套方法的合理性)非常常见,但是列表本身不需要父结构。列表地址只是第一个节点的地址
/** function to create list and allocates/initilizes head, set list->n = 0.
* returns new list on success, NULL otherwise.
*/
list_t *create_list (void)
{
node_t *head = NULL;
list_t *list = malloc (sizeof *list); /* allocate list */
if (!list) { /* validate/handle error */
perror ("create_list() malloc-list");
return NULL;
}
head = create_node (0); /* create the first node */
if (!head) /* validate/handle error */
return NULL;
list->head = head; /* initialize list values */
list->n = 0;
return list; /* return list */
}
在学习列表时,将管理列表的任务分解为简单的单独功能确实很有帮助。这使您能够集中精力(稍微容易一点)处理每个列表操作。例如,在列表中,您需要:
next
指针NULL
并设置数据
值李>
head
分配,并初始化列表结构中包含的任何附加信息李>
typedef struct node {
int data;
struct node *next;
} node_t;
typedef struct list {
struct node *head;
size_t n; /* at least make parent hold list size */
} list_t;
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#if ! defined (_WIN32) && ! defined (_WIN64)
#include <stdlib.h> /* Linux has malloc/free in the stdlib header */
#endif
typedef struct node {
int data;
struct node *next;
} node_t;
typedef struct list {
struct node *head;
size_t n; /* at least make parent hold list size */
} list_t;
/** function to create node and set data value to data.
* returns new node on success, NULL otherwise.
*/
node_t *create_node (int data)
{
node_t *newnode = malloc (sizeof *newnode); /* allocate */
if (newnode == NULL) { /* validate/handle error */
perror ("create_node() malloc-newnode");
return NULL;
}
newnode->data = data; /* initialize members */
newnode->next = NULL;
return newnode; /* return pointer to new node */
}
/** function to create list and allocates/initilizes head, set list->n = 0.
* returns new list on success, NULL otherwise.
*/
list_t *create_list (void)
{
node_t *head = NULL;
list_t *list = malloc (sizeof *list); /* allocate list */
if (!list) { /* validate/handle error */
perror ("create_list() malloc-list");
return NULL;
}
head = create_node (0); /* create the first node */
if (!head) /* validate/handle error */
return NULL;
list->head = head; /* initialize list values */
list->n = 0;
return list; /* return list */
}
/** add node to list, create list if list NULL, set node->data to data.
* return new node on success, NULL otherwise.
*/
node_t *add_node (list_t **list, int data)
{
node_t *node;
if (!*list) { /* handle list doesn't exist */
*list = create_list();
if (!*list)
return NULL;
node = (*list)->head; /* (..)-> required by operator precedence */
node->data = data;
}
else { /* list already exists */
node = (*list)->head; /* set node to list->head */
/* iterate over nodes to find last and add node at end */
while (node->next)
node = node->next;
node->next = create_node (data); /* allocate next node */
node = node->next; /* change to new node */
}
(*list)->n++; /* increment number of nodes in list */
return node; /* return node */
}
/** print the value of each node in list */
void prn_list (const list_t *list)
{
/* iterate over list printing data value */
for (node_t *node = list->head; node; node = node->next)
printf (" %d", node->data);
putchar ('\n'); /* tidy up with newline */
}
/** free all nodes in list and free list */
void free_list (list_t *list)
{
node_t *node = list->head; /* set node to head */
while (node) { /* iterate over each nod */
node_t *victim = node; /* setting victim to free */
node = node->next; /* change to next node */
free (victim); /* free victim */
}
free (list); /* free list */
}
int main (void)
{
list_t *list = NULL; /* just declare list and set pointer NULL */
for (int i = 0; i < 25; i++) /* add 25 nodes to list */
if (add_node (&list, i + 1) == NULL) /* validate each addition */
break;
/* print list content, beginning with number of nodes in list */
printf ("list contains: %lu nodes\n\n", list->n);
prn_list (list); /* followed by each node value */
free_list (list); /* and then delete list */
return 0;
}
在这里,我们简单地添加了一个计数器来跟踪列表中的节点数,作为一个附加的、有用的数据块来证明外部结构的合理性。它为您提供节点计数,而无需每次迭代列表即可获得(如果您需要该数据,这只是一个小小的效率改进)。通过一个简单的列表->n
,您可以获得列表中的节点数
按照我们的列表大纲,您需要一种为您的应用程序创建节点的方法
/** print the value of each node in list */
void prn_list (const list_t *list)
{
/* iterate over list printing data value */
for (node_t *node = list->head; node; node = node->next)
printf (" %d", node->data);
putchar ('\n'); /* tidy up with newline */
}
/** free all nodes in list and free list */
void free_list (list_t *list)
{
node_t *node = list->head; /* set node to head */
while (node) { /* iterate over each nod */
node_t *victim = node; /* setting victim to free */
node = node->next; /* change to next node */
free (victim); /* free victim */
}
free (list); /* free list */
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#if ! defined (_WIN32) && ! defined (_WIN64)
#include <stdlib.h> /* Linux has malloc/free in the stdlib header */
#endif
typedef struct node {
int data;
struct node *next;
} node_t;
typedef struct list {
struct node *head;
size_t n; /* at least make parent hold list size */
} list_t;
/** function to create node and set data value to data.
* returns new node on success, NULL otherwise.
*/
node_t *create_node (int data)
{
node_t *newnode = malloc (sizeof *newnode); /* allocate */
if (newnode == NULL) { /* validate/handle error */
perror ("create_node() malloc-newnode");
return NULL;
}
newnode->data = data; /* initialize members */
newnode->next = NULL;
return newnode; /* return pointer to new node */
}
/** function to create list and allocates/initilizes head, set list->n = 0.
* returns new list on success, NULL otherwise.
*/
list_t *create_list (void)
{
node_t *head = NULL;
list_t *list = malloc (sizeof *list); /* allocate list */
if (!list) { /* validate/handle error */
perror ("create_list() malloc-list");
return NULL;
}
head = create_node (0); /* create the first node */
if (!head) /* validate/handle error */
return NULL;
list->head = head; /* initialize list values */
list->n = 0;
return list; /* return list */
}
/** add node to list, create list if list NULL, set node->data to data.
* return new node on success, NULL otherwise.
*/
node_t *add_node (list_t **list, int data)
{
node_t *node;
if (!*list) { /* handle list doesn't exist */
*list = create_list();
if (!*list)
return NULL;
node = (*list)->head; /* (..)-> required by operator precedence */
node->data = data;
}
else { /* list already exists */
node = (*list)->head; /* set node to list->head */
/* iterate over nodes to find last and add node at end */
while (node->next)
node = node->next;
node->next = create_node (data); /* allocate next node */
node = node->next; /* change to new node */
}
(*list)->n++; /* increment number of nodes in list */
return node; /* return node */
}
/** print the value of each node in list */
void prn_list (const list_t *list)
{
/* iterate over list printing data value */
for (node_t *node = list->head; node; node = node->next)
printf (" %d", node->data);
putchar ('\n'); /* tidy up with newline */
}
/** free all nodes in list and free list */
void free_list (list_t *list)
{
node_t *node = list->head; /* set node to head */
while (node) { /* iterate over each nod */
node_t *victim = node; /* setting victim to free */
node = node->next; /* change to next node */
free (victim); /* free victim */
}
free (list); /* free list */
}
int main (void)
{
list_t *list = NULL; /* just declare list and set pointer NULL */
for (int i = 0; i < 25; i++) /* add 25 nodes to list */
if (add_node (&list, i + 1) == NULL) /* validate each addition */
break;
/* print list content, beginning with number of nodes in list */
printf ("list contains: %lu nodes\n\n", list->n);
prn_list (list); /* followed by each node value */
free_list (list); /* and then delete list */
return 0;
}
$ /bin/llsingle_w_parent
list contains: 25 nodes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
$ valgrind ./bin/llsingle_w_parent
==14749== Memcheck, a memory error detector
==14749== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==14749== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==14749== Command: ./bin/llsingle_w_parent
==14749==
list contains: 25 nodes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
==14749==
==14749== HEAP SUMMARY:
==14749== in use at exit: 0 bytes in 0 blocks
==14749== total heap usage: 26 allocs, 26 frees, 416 bytes allocated
==14749==
==14749== All heap blocks were freed -- no leaks are possible
==14749==
==14749== For counts of detected and suppressed errors, rerun with: -v
==14749== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)