链表功能:尾插节点、头插节点、向后遍历,向前遍历、搜索节点、删除节点、删除链表
主函数:
#include <stdio.h>
#include <stdlib.h>
int main()
{
//初始化链表头
list_node *head = NULL;
head = init_list(head);
//尾插节点
tail_add_node(head,10);
tail_add_node(head,20);
tail_add_node(head,30);
//头插节点
head_add_node(head,3);
head_add_node(head,5);
head_add_node(head,8);
//删除节点
delete_list_node(head,30);
//向后遍历链表
forward_show_list(head);
//向前遍历链表
backward_show_list(head);
//搜索节点
search_list_node(head,20);
//删除链表
delete_list(head);
return 0;
}
尾插节点:
void tail_add_node(list_node *head, int num)
{
list_node *node = NULL;
node = (list_node *)malloc(sizeof(list_node));
if(node == NULL)
printf("malloc node error!\n");
node->a = num;
node->prev = head->prev; //新节点的前驱节点连末尾节点(head->prev: 头节点的前驱等于末尾节点)
node->next = head; //新节点的后继节点连接头节点
head->prev->next = node; //末尾节点的后继节点连接新节点
head->prev = node; //头节点的前驱结点连接新节点
}
头插节点:
void head_add_node(list_node *head, int num)
{
list_node *node = NULL;
node = (list_node *)malloc(sizeof(list_node));
if(node == NULL)
printf("malloc node error!\n");
node->a = num;
//链接节点
node->prev = head; //新节点的前驱指向头节点
node->next = head->next; //新节点的后继 指向 头节点后面的一个节点
head->next->prev = node; //头节点的后面一个节点的前驱指向新节点(原本指向头节点)
head->next = node; //头节点的后继指向新节点
}
向后遍历:
void forward_show_list(list_node *head)
{
list_node *p = NULL;
for(p=head->next; p!=head; p=p->next)
{
printf("a = %d\n",p->a);
}
}
向前遍历:
void backward_show_list(list_node *head)
{
list_node *p = NULL;
for(p=head->prev; p!=head; p=p->prev)
{
printf("a = %d\n",p->a);
}
}
搜索节点:
int search_list_node(list_node *head, int num)
{
list_node *p = NULL;
//遍历链表查找指定值
for(p=head->next; p!=head; p=p->next)
{
if(p->a == num)
{
printf("already found!\n");
return 0;
}
}
return -1;
}
删除节点:
int delete_list_node(list_node *head, int num)
{
list_node *p = NULL;
list_node *q = NULL;
for(q=head,p=head->next; p!=head; q=p,p=p->next)
{
if(p->a == num)
{
q->next = p->next; //p节点的前一个节点后继连接p节点的后一个节点(p为要删除的节点)
p->next->prev = q; //p节点的后一个节点的前驱连接p节点的前一个节点
free(p); //释放p指向的那片空间
return 0;
}
}
return -1;
}
删除链表:
void delete_list(list_node *head)
{
list_node *p = NULL;
list_node *q = NULL;
head->prev->next = NULL; //先将末尾节点的后继节点给置为NULL,(原本指向head)使其循环链表不循环
for(p=q=head; p!=NULL; p=q) //开始p和q都指向头节点
{
q = p->next; //q指向后面一个节点
free(p); //释放p(p此时指向的是q的前面),执行for的p=q,此时p又与q指向同一个节点。
}
}