双向链表是在单链表的基础上增加了指向直接前驱的指针,所以在双向链表中的每一个节点都能很容易的找到他的前驱和后继。双向链表经常和循环链表一起使用,成为双向循环链表,他的尾指针的后继指向头结点,头结点的前驱指向尾节点,构成一个环的结果,这样,就算在尾节点也能很容易的找到头结点。
此处以双向链表为例
结构定义
typedef int ElemType;
typedef struct DulNode{
ElemType data;
struct DulNode *prior;//直接前驱指针
struct DulNode *next; //直接后继指针
}DulNode,*DuLinkList;
功能函数
//初始化
Status InitLink(DuLinkList *L){
*L = (DuLinkList)malloc(sizeof(DulNode));
if(!(*L))
return ERROR;
(*L)->prior = NULL;
(*L)->next = NULL;
}
//尾插法
DuLinkList CreateLinkListT(DuLinkList L){
ElemType n;
DuLinkList p = L;
printf("请输入要插入多少个元素:");
scanf("%d",&n);
for (int i = 1; i <= n; i++) {
DuLinkList q = (DuLinkList)malloc(sizeof(DulNode));
p->next = q;
printf("请输入第%d个元素的值:",i);
scanf("%d",&q->data);
q->prior = p;
q->next = NULL;
p = q;
}
return L;
}
void OutputLinkList(DuLinkList L){
DuLinkList p = L->next;
int i = 1;
while(p!=NULL){
printf("第%d个元素的值是:%d,前驱是:%d\n",i,p->data,p->prior->data);
p = p->next;
i++;
}
}
//双向链表第i个节点之间插入新的节点
DuLinkList InsertLinkList(DuLinkList L,int i,ElemType e){
DuLinkList p,q;
int j;
p = L;
//找到第i个节点前一个节点
for(j=1;j<i;j++){
p = p->next;
}
q = (DuLinkList)malloc(sizeof(DulNode));
if(q){
q->data = e;
p->next->prior = q;
q->next = p->next;
p->next = q;
q->prior = p;
}
return L;
}
//删除第i个节点
DuLinkList DeleteLinkList(DuLinkList L,int i){
DuLinkList p,q;
p = L->next;
q = L;
int j;
//找到第i个节点p,和第i-1个节点q
for(j=1;j<i;j++){
p = p->next;
q = q->next;
}
p->next->prior = q;
q->next = p->next;
free(p);
return L;
}
main函数
int main() {
DuLinkList L;
InitLink(&L);
CreateLinkListT(L);
OutputLinkList(L);
int i;
ElemType e;
printf("请输入要在第几个元素之前插入新节点:");
scanf("%d",&i);
printf("请输入要插入的数值:");
scanf("%d",&e);
InsertLinkList(L,i,e);
OutputLinkList(L);
printf("请输入要删除第几个节点:");
scanf("%d",&i);
DeleteLinkList(L,i);
OutputLinkList(L);
return 0;
}