使用哨兵(头节点)
实现双向循环链表,所谓哨兵(头结点):哑对象,简化边界条件处理。假设在链表L中设置一个对象L.nil ,该对象 代表NIL,但也具有和其他对象相同的各个属性。对于链表代码中出现的每一处对NIL的引用,都替换成L.nil 。
这样的调整将一个常规的双向链表变成一个有哨兵的双向循环链表。哨兵位于表头和表尾之间。
L.nil.next 指向表头, L.nil.prev 指向表尾。
#include <stdio.h>
#include <stdlib.h>
#define ElemType int
typedef struct DLINKLIST{
ElemType data;
struct DLINKLIST *prev;
struct DLINKLIST *next;
}DoubleLinkList;
/*
* according to the lib c
* return 0 means successful
* return -1 means failed
*
* our double-link-list has a NIL node !
*/
int init_dlinklist(DoubleLinkList *list)
{
if ((list = (DoubleLinkList *)malloc(sizeof(DoubleLinkList))) == NULL) {
perror("error: init malloc");
return -1;
}
list->data = 0;
list->prev = list;
list->next = list;
return 0;
}
DoubleLinkList * search_dlinklist(DoubleLinkList *list, ElemType target)
{
DoubleLinkList *tmp = list->next;
while (tmp != list && tmp->data != target)
tmp = tmp->next;
return tmp;
}
int del_dlinklist(DoubleLinkList *list, DoubleLinkList *target)
{
if (target == list)
return -1;
target->next->prev = target->prev->next;
target->prev->next = target->next;
return 0;
}
int insert_dlinklist(DoubleLinkList *list, ElemType target)
{
DoubleLinkList *tmp;
if ((tmp = (DoubleLinkList *)malloc(sizeof(DoubleLinkList))) == NULL) {
perror("error: insert malloc error");
return -1;
}
tmp->data = target;
tmp->next = list->next;
list->next->prev = tmp;
list->next = tmp;
tmp->prev = list;
return 0;
}