双向链表示意图如下:
使用C语言实现双向链表,包括创建链表、遍历显示、插入、删除、清除链表、反转链表等操作。
#include <stdio.h>
#include <iostream>
//双向链表
#define CHECK_PARAMENT_NULL(p) \
if((p) == NULL){ \
return -1; \
} \
(void)0
typedef struct node
{
int data;
struct node *prev;
struct node *next;
}list_node;
//创建双向链表
int create_list(list_node **list_head)
{
CHECK_PARAMENT_NULL(list_head);
list_node *head = (list_node *)malloc(sizeof(list_node));
list_node *tail = (list_node *)malloc(sizeof(list_node));
head->data = 0;
head->prev = NULL;
head->next = tail;
tail->data = 0;
tail->prev = head;
tail->next = NULL;
*list_head = head;
return 0;
}
//通过头结点清除双向链表
int destroy_list(list_node **head)
{
CHECK_PARAMENT_NULL(head);
CHECK_PARAMENT_NULL(*head);
std::cout << "开始清除双向链表" << std::endl;
list_node *p = (*head)->next;
std::cout << "清除头节点" << std::endl;
free((*head));
*head = NULL;
while (p->next != NULL)
{
list_node *tmp = p;
p = p->next;
std::cout << "清除节点,节点值=" << tmp->data << std::endl;
free(tmp);
tmp = NULL;
}
free(p);
p = NULL;
std::cout << "清除尾节点"<< std::endl;
std::cout << "完成清除双向链表" << std::endl;
return 0;
}
//遍历输出
int display_list(list_node *head)
{
if (head == NULL)
{
std::cout << "输入为NULL" << std::endl;
return -1;
}
list_node *p = head->next;
while (p->next != NULL)
{
std::cout << p->data << " ";
p = p->next;
}
std::cout << endl;
return 0;
}
//在index位置后插入值为data的节点,没有找到index则插到最后
int insert_node(list_node *head, int index, int data)
{
CHECK_PARAMENT_NULL(head);
list_node *p = head->next;
while (p->next != NULL)
{
if (p->data == index)
{
std::cout << "找到值为" << index << "的节点,插入值为" << data << "的节点" << endl;
list_node *node = (list_node *)malloc(sizeof(list_node));
node->data = data;
list_node *tmp = p->next;
p->next = node;
node->prev = p;
node->next = tmp;
tmp->prev = node;
return 0;
}
p = p->next;
}
std::cout << "没有找到值为" << index << "的节点,将节点" << data << "插到尾部" << endl;
list_node *node = (list_node *)malloc(sizeof(list_node));
node->data = data;
list_node *tmp = p->prev;
p->prev = node;
tmp->next = node;
node->prev = tmp;
node->next = p;
return 0;
}
//删除index值的节点
int delete_node(list_node *head, int index)
{
CHECK_PARAMENT_NULL(head);
list_node *p = head->next;
while (p->next != NULL)
{
if (p->data == index)
{
std::cout << "找到值为" << index << "的节点,删除之" << endl;
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
p = NULL;
return 0;
}
p = p->next;
}
std::cout << "没有找到值为" << index << "的节点,无法删除" << endl;
return 0;
}
//反转链表,输入head,返回反转之后链表的head
int reverse_list(list_node **head)
{
CHECK_PARAMENT_NULL(head);
CHECK_PARAMENT_NULL(*head);
std::cout << "反转链表" << endl;
//先处理head节点
list_node *p = (*head)->next;
(*head)->next = NULL;
(*head)->prev = p;
while (p->next != NULL)
{
list_node *tmp = p->next;
p->next = p->prev;
p->prev = tmp;
p = tmp;
}
//最后处理tail节点
p->next = p->prev;
p->prev = NULL;
(*head) = p;
return 0;
}
int main(void)
{
list_node *head = NULL;
create_list(&head);
insert_node(head, 5, 1);
display_list(head);
insert_node(head, 1, 2);
display_list(head);
insert_node(head, 2, 3);
display_list(head);
insert_node(head, 10, 4);
display_list(head);
delete_node(head, 4);
display_list(head);
reverse_list(&head);
display_list(head);
destroy_list(&head);
display_list(head);
int a;
std::cin >> a;
return 0;
}
测试输出如下: