双链表的结点包括3个域,一个是存放数据信息的info域,另外两个是指针域,
双链表的结构定义如下
typedef struct dlink_node{
datatype info;
struct dlink_node *llink,*rlink;
}dnode;
双链表中第一个结点没有前驱,它的llink域为NULL;最后一个结点没有后继它的rlink域为NULL;结点中的rlink域作用和单链表结点的next域一样,因此双链表的一些基本操作的实现并不复杂,
- 建立一个空的双链表
dnode *init(){
return NULL;
}
- 输出双链表中的各个结点的值
void display(dnode *head){
dnode *p;
printf("\n");
p = head;
if(!p){
printf("\n 双链表是空的!");
}else{
while(p){
printf("%5d",p->info);
p = p->rlink;
}
}
}
- 查找双链表的第i个结点的值
dnode *find(dnode *head,int i){
dnode *p = head;
int j=1;
if(i < 1){
printf("\n 第%d 个结点不存在!\n",i);
return NULL;
}
while(p && i!=j){ /*没有找完整个表并且没有找到*/
p = p->rlink;
j++; /*继续沿着右指针向后查找,计数器加1 */
}
if(!p){
printf("\n第%d 个结点不存在!\n");
return NULL;
}
return p;
}
- 双链表的插入操作
对于双链表的插入操作,如果要在双链表中q所指向的结点后插入一个新的结点p,其中要涉及的结点有q指向的结点、p指向的结点以及q的后继结点(q->rlink 指向的结点),要设置或修改的只有4个指针,具体要做的设置为:p的rlink的设置为q的后继结点(q->rlink);p的llink的设置为q;q的后继结点的前驱为(q->rlink->llink)修改为p;q的后继结点(q->rlink)修改为p。对于特殊情形,双链表同单链表一样需要做特殊处理。
dnode *insert(dnode *head,datatype x,int i){
dnode *p,*q;
p = (dnode *)malloc(sizeof(dnode));
p->info = x;
if(i == 0){
p->llink = NULL; /*新插入的结点没有前驱*/
p->rlink = head; /*新插入的结点的后继是原来双链表中的第一个结点*/
if(!head){
head = p;
}
else{
head->llink = p; /*原来双链表中第一个结点的前驱是新插入的结点*/
head = p; /*新结点成为双链表的第一个结点*/
}
return head;
}
q = find(head,i);
if(!q){
printf("第%d 个结点不存在,无法进行插入");
free(q);
return head;
}
if(q->rlink == NULL){ /*在最后一个结点后插入*/
p->rlink = q->rlink;
p->llink = q;
q->rlink = p;
}else{ /*一般情况下的插入(中间插入)*/
p-rlink = q-rlink;
p->llink = q;
q->rlink->llink = p;
q->rlink = p;
}
return head;
}
双链表的删除操作
dnode *dele(dnode *head,datatype x){
dnode *q;
if(!head){
printf("\n 双链表为空,无法进行删除\n");
return head;
}
q = head;
while(q&&q->info!=x)
q = q->rlink;
if(!q){
printf("\n 没有找到值为%d 的结点! 不做删除操作!\n",x);
}
if(q == head &&head->rlink){ /*被删除的结点是第一个结点并且表中不止一个结点*/
head = head->rlink;
head->llink = NULL;
free(q);
return head;
}
if(q == head && !head->rlink){ /*被删除的结点是第一个结点并且表中只有一个结点*/
free(q);
return NULL; /*双链表置空*/
}else{
if(!q->rlink){ /*被删除的结点是双链表的最后一个结点*/
q->llink->rlink = NULL;
free(q);
return head;
}else{
q->llink-rlink = q->rlink;
q->rlink-llink = q->llink;
free(q);
return head;
}
}
}