(注意:这里第一个结点的bwd为NULL,最后一个节点的fwd位NULL。)
要将一个节点插入到双链表中,有几种情况:
1、插入链表中间位置
2、插入链表起始位置
3、插入链表结束位置
4、原链表为空,相当于既要插入起始位置,又插入结束位置。
每种情况有4个指针必须修改:
在1,2 两种情况下新节点fwd字段必须设置为指向链表的下一个节点,链表下一个节点的bwd字段必须指向这个新节点。
在3,4两种情况下,新节点的fwd字段字段必须设置为NULL,根节点的fwd必须指向这个新节点。
在1,3两种情况下,新节点的bwd字段必须设置为指向链表的前一个节点,而链表前一个节点的fwd字段必须设置为新节点。
在2,4两种情况下,新节点的bwd字段必须设置为NULL,根节点的fwd必须设置为新节点。
- 版本一:
#define TRUE 1
#define FALSE 0
#define NUL '\0'
typedef struct NODE {
struct NODE *fwd;
struct NODE *bwd;
int value;
} Node;
int dll_insert(Node **rootp, int new_value) {
Node *this;
Node *next;
Node *new_node;
//找到要插入的位置
//如果找到value相同的元素,直接返回FALSE
for(this = rootp; (next = this->fwd) != NULL; this = next) {
if(next->value == value) {
return FALSE;
}
if(next->value > value) {
break;
}
}
new_node = (Node*) malloc(sizeof(Node));
if(new_node == NULL) {
printf("malloc failed\n");
return -1;
}
//插入新值
if(next != NULL) {
//情况1,2:没有位于链表尾部
if(this != rootp) {//情况1:没有在链表头部
new_node->fwd = next;
this->fwd = new_node;
new_node->bwd = this;
next->bwd = new_node;
} else {//情况2:在链表头部
new_node->fwd = next;
rootp->fwd = new_node;
new_node->bwd = NULL;
next->bwd = new_node;
}
} else {
//情况3,4:位于链表尾部
if (this != rootp) {//情况3: 没有在链表头部
new_node->fwd = NULL;
this->fwd = new_node;
new_node->bwd = this;
rootp->bwd = new_node;
} else {
//情况3: 在链表头部
new_node->fwd = NULL;
rootp->fwd = new_node;
new_node->bwd = NULL;
rootp->bwd = new_node;
}
}
return TRUE;
}
- 版本二:
版本一中有很多if判断,分支里有很多冗余的代码,我们提炼出一些共性,精简后:
#define TRUE 1
#define FALSE 0
#define NUL '\0'
typedef struct NODE {
struct NODE *fwd;
struct NODE *bwd;
int value;
} Node;
int dll_insert(Node **rootp, int new_value) {
Node *this;
Node *next;
Node *new_node;
//找到要插入的位置
//如果找到value相同的元素,直接返回FALSE
for(this = rootp; (next = this->fwd) != NULL; this = next) {
if(next->value == value) {
return FALSE;
}
if(next->value > value) {
break;
}
}
new_node = (Node*) malloc(sizeof(Node));
if(new_node == NULL) {
printf("malloc failed\n");
return -1;
}
new_node->value = value;
//插入新节点
new_node->fwd = next;
this->fwd = new_node;
if(this != NULL) {
new_node->bwd = this;
} else {
new_node->bwd = NULL;
}
if(next != NULL) {
next->bwd = new_node;
} else {
rootp->bwd = new_node;
}
return TRUE;
}