有序雙鏈表
typedef struct NODE {
struct NODE* fwd;
struct NODE* bwd;
int value;
}Node;
fwd指向下一個節點,bwd指向前一個節點。
可能的情況:
1)新值插入到鏈表中間位置;
2)新值插入到鏈表的起始位置;
3)新值插入到鏈表的結束位置;
4)新值插入到鏈表的起始位置,又插入到鏈表的結束位置(原鏈表爲空)。
/*
**把一個值插入到一個雙鏈表,rootp是一個指向根節點的指針,
**value是要插入的新值
**返回值:如果要插入的值已經存在,返回0
**如果內存不足導致無法插入,返回-1,如果插入成功,返回1。
*/
#include <stdlib.h>
#include <stdio.h>
#include "doubly_linked_list_node.h"
int
dll_insert(Node *rootp, int value)
{
Node *this;
Node *next;
Node *newnode;
/*
**查看value是否已經存在於鏈表中,如果是就返回
**否則,創建一個新節點(讓newnode指向它)
**“this”將指向應該在新節點之前的那個節點
**“next”蔣指向應該在新節點之後的那個節點
*/
for(this = rootp; (next = this->fwd) != NULL; this = next){
if(next->value == value)
return 0;
if(next->value > value)
break;
}
newnode = (Node*)malloc(sizeof(Node));
if(newnode = NULL)
return -1;
newnode->value = value;
/*
**把新節點添加到鏈表中
*/
if(next != NULL){
/*
**情況1/2:不位於鏈表尾部
*/
if(this != rootp){ /*情況1:不在起始位置*/
newnode->bwd = this;
newnode->fwd = next;
this->fwd = newnode;
next->bwd = newnode;
}
else{ /*情況2:位於鏈表起始位置*/
rootp->fwd = newnode;
next->bwd = newnode;
newnode->bwd = NULL;
newnode->fwd = next;
}
}
else{
/*
**情況3/4:位於鏈表的尾部
*/
if(this != NULL){ /*情況3:位於結束位置,不在起始位置*/
newnode->fwd = NULL;
newnode->bwd = this;
this->fwd = newnode;
rootp->bwd = newnode;
}
else{ /*情況4:位於鏈表起始位置也位於結束位置*/
newnode->fwd = NULL;
newnode->bwd = NULL;
rootp->fwd = newnode;
rootp->bwd = newnode;
}
return 1;
}
技巧一:statement factoring:
各個嵌套的if語句內存在大量相似之處,所以把他們提煉出來
/*
**把新節點添加到鏈表中
*/
if(next != NULL){
/*
**情況1/2:不位於鏈表尾部
*/
newnode->fwd = next;
if(this != rootp){ /*情況1:不在起始位置*/
newnode->bwd = this;
this->fwd = newnode;
}
else{ /*情況2:位於鏈表起始位置*/
rootp->fwd = newnode;
newnode->bwd = NULL;
}
next->bwd = newnode;
}
else{
/*
**情況3/4:位於鏈表的尾部
*/
newnode->fwd = NULL;
if(this != NULL){ /*情況3:位於結束位置,不在起始位置*/
newnode->bwd = this;
this->fwd = newnode;
}
else{ /*情況4:位於鏈表起始位置也位於結束位置*/
newnode->bwd = NULL;
rootp->fwd = newnode;
}
rootp->bwd = newnode;
}
return 1;
}
技巧二:邏輯提煉
情況3/4的第一條,this=NULL的時候賦值給newnode->bwd=NULL相當於newnode->bwd=this,
/*
**把新節點添加到鏈表中
*/
newnode->fwd = next;
if(this != rootp){ /*情況1:不在起始位置*/
newnode->bwd = this;
this->fwd = newnode;
}
else{ /*情況2:位於鏈表起始位置*/
rootp->fwd = newnode;
newnode->bwd = NULL;
}
if(next != NULL)
next->bwd = NULL;
else
rootp->bwd = newnode;