说明
对链表的熟练操作,对嵌入式的数据存储能达到精益求精的效果,减少在编写项目时出现BUG。接下来我会编写单链表,双向循环链表,内核链表的代码供大家参考。
1.确定结构体成员
确定单链表的存放的是什么数据,从而确定每个节点的成员。例如:
struct linklist
{
int data;
struct linklist *next;
};
上面这个就是数据域只有一个data,但是我们在做项目的时候往往不会只有一个data数据。而是一个人的信息,那这时我们可以这样
struct info
{
char name[20];
char work[20];
char pic_path[64];
};
struct linklist
{
struct info person;
struct linklist *next;
};
2.创建一个新节点
有了节点,那我们就要给这个节点进行初始化(这个初始化决定了他是循环还是不循环),以及为节点申请空间。代码如下:
//申请节点
struct linklist *request_list_node(int insert_data)
{
struct linklist *new_node;
new_node = malloc(sizeof(struct linklist));
if(new_node == NULL)
{
perror ("申请节点失败\n");
return NULL;
}
new_node->data = insert_data;
new_node->next = NULL;
return new_node;
}
3.销毁一个节点
申请了节点,就有销毁节点,如果不销毁的话,会占用内存。
//销毁节点
void destory_node(struct linklist *node)
{
free(node);
}
4.插入节点(头插)
void insert_data_to_head(struct linklist *head,struct linklist *new_node)
{
new_node->next = head->next;
head->next = new_node;
}
5.遍历链表
//遍历链表
void display_list_node(struct linklist *head)
{
struct linklist *pos;
for(pos = head->next; pos != NULL; pos = pos->next)
{
printf("%d ",pos->data);
}
printf("\n");
}
6.创建链表
有了上面这几个函数,我们就可以创建和显示我们链表的数据啦。
那么如何在main函数中创建呢。下面是创建头节点,然后源源不断地往头节点中插入数据
struct linklist *head;
head = request_list_node(-1);
if(head == NULL)
{
printf("链表创建失败\n");
return -1;
}
7.插入数据
循环执行下面代码就可以一直插入数据啦
printf("要插入的数据是:\n");
scanf("%d",&data);
new_node = request_list_node(data);
insert_node_to_list(head,new_node);
8.判断链表是否为空
//判断链表是否为空
bool list_is_empty(struct linklist *head)
{
if(head->next == NULL)
{
return 1;
}
else
{
return 0;
}
}
9.删除数据
下面是删除头节点后面的节点,如果要删除链表尾部和指定数据那就要增加一些判断条件了
//删除节点
bool del_list_node(struct linklist *head)
{
if(list_is_empty(head))
{
printf("链表空了\n");
return 0;
}
else
{
struct linklist *rmnode = head->next;
head->next = rmnode->next;
destory_node(rmnode);
return 1;
}
}
9.修改数据
void modify_data(struct linklist *head,int find_data,int new_data)
{
struct linklist *pos = head->next;
if(pos == NULL)
{
printf("链表为空\n");
}
while(pos != NULL)
{
if(pos->data == find_data)
{
pos->data = new_data;
}
pos = pos->next;
}
}
10.主函数
int main(void)
{
struct linklist *head,*new_node;
struct linklist *pos,*rmnode;
int cmd;
int data,find_data;
head = request_list_node(-1);
if(head == NULL)
{
printf("链表创建失败\n");
return -1;
}
while(1)
{
printf("1.插入数据 2.删除指定数据 3.显示链表 4.修改数据 5.尾插数据\n");
scanf("%d",&cmd);
switch(cmd)
{
case 1:
printf("要插入的数据是:\n");
scanf("%d",&data);
new_node = request_list_node(data);
insert_node_to_list(head,new_node);
break;
case 2:
printf("要删除的数据是:\n");
scanf("%d",&data);
del_data_node(head,data);
break;
case 3:
display_list_node(head);
break;
case 4:
printf("要修改的数据是:\n");
scanf("%d",&find_data);
printf("修改后的数据是:\n");
scanf("%d",&data);
modify_data(head,find_data,data);
break;
case 5:
printf("要插入的数据是:\n");
scanf("%d",&data);
new_node = request_list_node(data);
insert_data_to_tail(head,new_node);
break;
default:
break;
}
}
}
11.运行结果
12.结束语
本次单链表的文章就结束啦,这种还是要自己写过一次才会更加熟练的,还有很多扩展的,比如将单链表中的数据从小到大插入,删除指定的所有数据,移动数据。下一次我还会更新双向循环链表。