1.双向链表的数据结构
typedef char DLinkType;
typedef struct DLinkNode
{
DLinkType data;
struct DLinkNode* next;
struct DLinkNode* prev;
}DLinkNode;
双向带头结点的链表有三个成员, 一个是数据, 一个是指针 next 指向当前结点的下一个结点, 一个指针 prev 指向当前结点的 前一个结点,即每一个节点都有一个直接的前驱, 一个直接的后继, 这里只讨论带头结点的双向链表。
2.双向链表的初始化
/*
*
* 初始化双链表
*
*/
void DLinkListInit(DLinkNode** phead)
{
if(phead == NULL)
{
return;//非法输入
}
*phead = (DLinkNode*)malloc(sizeof(DLinkNode));
(*phead) -> data = 0;
(*phead) -> next = *phead;
(*phead) -> prev = *phead;
}
带头结点双向链表的初始化即就是用一个傀儡节点代表其为空,这里将头节点的数据初始化为 0, 注意,双向链表中没有空指针,所以将双向链表的头节点的 next 指向它自己, 将双向链表的 prev 指向它自己,即判断一个双向带头节点的链表是否为空的条件就是head -> next == head 或者是 head -> prev == head。
3.创建一个新节点
既然需要对链表进行插入数据, 那便需要对其创建一个指定数据的节点,然后将其插入到当前的链表中。创建一个节点就是对其先分配空间, 再将节点对应的数据改为需要的目标数据。
/*
*
* 创建一个新节点
*
*/
DLinkNode* DLinkNodeCreat(DLinkType value)
{
DLinkNode* new_node = (DLinkNode*)malloc(sizeof(DLinkNode));
if(new_node == NULL)
{
return NULL;//内存分配失败
}
new_node -> data = value;
new_node -> next = new_node;
new_node -> prev = new_node;
return new_node;
}
4.头插一个新结点
&enap; &enap;对双向链表的头插节点也就是先创建一个新结点,然后定义一个指针 prev 指向头结点的下一个节点, 即prev = head -> next, 然后修改对应的 prev 和 所创建的新结点 new_node 的指向, 即 让 prev -> next = new_node, 再让new_node -> prev = prev,就OK了