引用百度百科的概念:
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
特点:
- 每个数据结点中都有两个指针
- 直接后继(下一个节点的地址)
- 直接前驱(上一个节点的地址)
双向链表和单向链表的区别就在于一个有两个方向(即前、后),一个只有一个方向。在结构上也是类似的,所需要实现的功能也是增、删、改、查。
- 增
//双向链表节点
typedef struct double_list
{
struct double_list *next;
struct double_list *prev;
int date;
}DOUBLE_LIST,*DOUBLE_LIST_P;
//新建头节点
DOUBLE_LIST_P Create_Head_Node()
{
//申请头节点空间
DOUBLE_LIST_P head = calloc(1, sizeof(DOUBLE_LIST));
if (head == NULL)
{
perror("head memory request failed!\n");
return NULL;
}
//初始化数据域
head->date = 0;
//初始化指针域
head->next = head;
head->prev = head;
return head;
}
//新建节点
DOUBLE_LIST_P Create_New_Node(int date)
{
DOUBLE_LIST_P New_node = calloc(1, sizeof(DOUBLE_LIST));
if (New_node == NULL)
{
perror("New_node memory request failed!\n");
return NULL;
}
//初始化数据域
New_node->date = date;
//初始化指针域
New_node->next = New_node;
New_node->prev = New_node;
return New_node;
}
//尾插法
bool Tail_insert(DOUBLE_LIST_P head, DOUBLE_LIST_P new_node)
{
//判断接收的头节点和新节点是否为空
if (new_node == NULL)
{
perror("New_node memory receive failed!\n");
return false;
}
if (head == NULL)
{
perror("head memory receive failed!\n");
return false;
}
new_node->prev = head->prev;
new_node->next = head;
head->prev->next = new_node;
head->prev = new_node;
return true;
}
这里要注意的是插入数据时要确保节点地址不丢失,如图
- 查
//查找数据
DOUBLE_LIST_P Find_Date(DOUBLE_LIST_P head, int date)
{
if (head == NULL)
{
perror("head memory receive failed!\n");
return false;
}
DOUBLE_LIST_P p = NULL;
for (p = head->next; p != NULL; p = p->next)
{
if(p->date == date)
{
return p;
}
}
return NULL;
}
//遍历链表
bool Show_List(DOUBLE_LIST_P head)
{
//判断接收的头节点是否为空
if (head == NULL)
{
perror("head memory receive failed!\n");
return false;
}
DOUBLE_LIST_P p = NULL;
for (p = head->next; p != head; p = p->next)
{
printf("%d\t", p->date);
}
printf("\n");
return true;
}
- 删
//删除数据
bool Delete_Date(DOUBLE_LIST_P node)
{
if (node == NULL)
{
perror("node memory receive failed!\n");
return false;
}
DOUBLE_LIST_P p = node->prev;
p->next = node->next;
node->next->prev = p;
node->next = NULL;
node->prev = NULL;
free(node);
return true;
}
- 改
//修改数据
bool Change_Date(DOUBLE_LIST_P node,int date)
{
if (node == NULL)
{
perror("node memory receive failed!\n");
return false;
}
node->date = date;
return true;
}