题目描述
双向链表是在结点中既保存了后一个结点指针又保存了前一个结点指针的链表。这种链表较单向链表而言能够快速查找某一结点的前后结点。下面给出双向链表的定义、插入以及删除算法描述。
图1:双向链表示例
(a)结点结构;(b)空的双向循环链表;(c)含有三个结点的双向循环链表
图2:双向链表的定义以及创建
双向链表在插入与删除时一定要注意其操作步骤的顺序。下面给出双向链表在插入与删除时的图示。
图3:双向链表插入与删除的图示
(a)双向链表的删除操作;(b)双向链表的插入操作
图4:双向链表的查找以及插入
图5:双向链表的删除操作
输入格式
输入数据只有一组,包含很多行。每行有1~3个整数。第一个整数如果是0,则表示输出双向链表中的所有元素;第一个整数如果是1,表示插入1个整数,其后跟2个整数i、e代表在第i个位置插入e;第一个整数如果是2,表示删除1个整数,其后跟1个整数i,表示删除的位置为i。
起始双向链表为空表。保证链表中每个元素不会重复,同时所有的操作都合法。
输出格式
当需要输出双向链表中的所有元素时输出,每次输出一行。整数间用一个空格隔开。
样例输入
复制
1 1 2 0 1 2 7 0 2 1 0 1 2 4 1 3 5 1 2 6 0 2 3 0
样例输出
复制
2 2 7 7 7 6 4 5 7 6 5
#include<stdio.h>
#include<malloc.h>
typedef struct dualnodelink{
int num;
int len;
struct dualnodelink *next;
struct dualnodelink *prior;
}*nodelink,node;
void show(nodelink l1);
void insert(nodelink l1,int i,int e);
void _delete(nodelink l1,int i);
int main(){
nodelink head=(nodelink)malloc(sizeof(node));
head->next=head;
head->prior=head;
head->len=0;
nodelink p=head;
int n;
int i,e;
while(~scanf("%d",&n)){
switch (n) {
case 0:
show(p);
break;
case 1:
scanf("%d %d",&i,&e);
insert(p,i,e);
break;
case 2:
scanf("%d",&i);
_delete(p,i);
break;
}
}
return 0;
}
void insert(nodelink l1,int i,int e){
nodelink p=l1;
int j=0;
if(i==l1->len+1||i>=1&&i<=l1->len){
while(j<i){
p=p->next;
j++;
}
nodelink nd=(nodelink)malloc(sizeof(node));
nd->num=e;
nd->prior=p->prior;
p->prior->next=nd;
nd->next=p;
p->prior=nd;
l1->len++;
}
}
void _delete(nodelink l1,int i){
nodelink p=l1;
int j=0;
while(j<i){
p=p->next;
j++;
}
p->prior->next=p->next;
p->next->prior=p->prior;
l1->len--;
free(p);
}
void show(nodelink l1){
nodelink p=l1;
int j=0;
while(j<l1->len){
p=p->next;
j++;
printf("%d ",p->num);
}
printf("\n");
}