1,双链表的基本操作
双链表可以避免单链表只能访问后继的缺陷,但其副作用也是十分明显的(额外的前驱指针,操作复杂一点)。
1.1 结构定义
较之单链表,双向链表多了一个指向前驱的指针。在整个双向链表中,头结点的前驱指针以及最后一个结点的后继指针为空。
结构定义如下:
typedef struct node{
int data;
node *prior;
node *next;
}Node;
1.2 添加结点
较之单链表,双链表在添加结点时不只是修改后继指针,还要修改新添加结点的前驱指向。
Status addNode(Node **dList,int x){//添加元素x
Node *q=0;
Node *p=(Node*)malloc(sizeof(Node));
if(!p)
return NO;
for(q=(*dList);q->next;q=q->next);
p->data=x;
q->next=p;
p->prior=q;
p->next=NULL;
(*dList)->data++;
return OK;
}
1.3 插入结点
插入一个结点必须找到欲插入位置的前驱或者后继,此例采用的是找到欲插入位置的前驱。
Status insertNode(Node **dList,int loc){//按位置插入
int i=0;
Node *p=0,*q=0;
if((*dList)->data==0)
return NO;
for(p=(*dList)->next,i=1;p->next,i!=loc;p=p->next,i++);
if(i==loc){
q=(Node*)malloc(sizeof(Node));
if(!q)
return NO;
printf("input your element:");
scanf("%d",&(q->data));
q->next=p->next;
p->next->prior=q;
p->next=q;
q->prior=p;
return OK;
}
else
return NO;
}
1.4 删除结点
删除某个结点也很简单,同样是修改前驱和后继。
Status removeNode(Node **dList,int x){//删除元素x
int i=0;
Node *p=0,*q=0;
if((*dList)->data==0)
return NO;
for(p=(*dList)->next,i=(*dList)->next->data;p->next,i!=x;p=p->next,i=p->data);
if(i==x){
if(!p->next){
p->prior->next=NULL;
free(p);
return OK;
}
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
return OK;
}
else
return NO;
}
2 总结
双链表的基本操作都很简单,如果有什么问题的话,那多半是语言没掌握好,就该数据结构本身而言不存在什么难度。虽然基本操作简单,但是基于链表的很多算法都很巧妙,需要自己花时间多练习 题目。