1.链表
链表可以按照链式存储多个结构体类型的数据,在C语言中使用要指向的结构体类型的指针来指向下一个节点(类似于python中单链表使用class Node里的node.next属性)。
使用一个记录个人信息的结构体来进行链表的演示:
#include "stdio.h"
typedef struct NAMENOTE
{
int id;
char *name;
char *tel_num;
struct NAMENOTE *p_next;
}NameNote;
int main()
{
NameNote c = {1, "C", "123456789", NULL};
NameNote python = {2, "python", "654654689", NULL};
NameNote java = {3, "Java", "165432789", NULL};
//将上述三个结构体对象链接为一个链表
c.p_next = &python;
python.p_next = &java;
printf("id:%-5d, name:%-10s, telephone number:%-11d", c.id, c.name, c.tel_num);
printf("id:%-5d, name:%-10s, telephone number:%-11d", c.p_next->id, c.p_next->name, c.p_next->tel_num);
printf("id:%-5d, name:%-10s, telephone number:%-11d", c.p_next->p_next->id, c.p_next->p_next->name, c.p_next->p_next->tel_num);
return 0;
}
2. 结构体内部声明本结构体类型的指针
在一个结构体中声明一个本结构体的指针不能用 typedef 起的别名,只能用 struct+结构体名* 来声明。
typedef struct NAMENOTE
{
int id;
char *name;
char *tel_num;
struct NAMENOTE *p_next; //在此处使用 NameNote *p_next 声明指针是错误的,因为还没有完成typedef的声明
}NameNote;
3.链表的遍历
遍历链表首先需要找到一个链表的头节点(或头指针)。
#include <stdio.h>
typedef struct NAMENOTE
{
int id;
char *name;
char *tel_num;
struct NAMENOTE *p_next;
}NameNote;
int main()
{
//1.声明三个节点
NameNote c = {1, "C", "111", NULL};
NameNote python = {2, "python", "222", NULL};
NameNote java = {3, "java", "333", NULL};
NameNote *p_flag = &c;
//2.将这三个节点进行链接
c.p_next = &python;
python.p_next = &java;
//3.进行遍历
while(p_flag != NULL)
{
printf("id:%-5d, name:%-10s, telephone number:%-11s\n", p_flag->id, p_flag->name, p_flag->tel_num);
p_flag = p_flag->p_next;
}
return 0;
}
4.手动添加链表
本次的手动添加链表的思想是先创建一个 struct 对象,再使用该对象进行链接。
注:本次不使用头指针指向头节点的方法
#include <stdio.h>
typedef struct NAMENOTE
{
int id;
char *name;
char *tel_num;
struct NAMENOTE *p_next;
}NameNote;
void AppendNode(NameNote *head_node, NameNote *append_node);
int main()
{
//1.声明三个节点
NameNote c = {1, "C", "111", NULL};
NameNote python = {2, "python", "222", NULL};
NameNote java = {3, "java", "333", NULL};
NameNote *p_flag = &c;
return 0;
}
void AppendNode(NameNote *head_node, NameNote *append_node)
{
while(head_node->p_next != NULL)
{
head_node = head_node->p_next;
}
head->p_next = append_node;
return;
}