双链表的操作与单链表其实差不多,多了一个prior后继指针指向前驱指针。
指针域:用于指向当前节点的直接前驱节点;
数据域:用于存储数据元素。
指针域:用于指向当前节点的直接后继节点;
增删改查的过程一定要多理解,可以通过画图理清过程。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef int ElemType;
//定义单链表结构
typedef struct DNode
{
ElemType data;//数据域
struct DNode *next,*prior;//前驱和后继指针
} DNode,* DLinkList;//此处DNode和DLinkList是等价的
//使用尾插法建表
bool CreatList(DLinkList &L){
int x;
L = (DLinkList)malloc(sizeof(DNode));//定义表头
L->next = NULL;
L->prior = NULL;//初始化表
DNode *s,*r;//r:表尾指针指向头结点
r = L;//将尾指针指向头指针
scanf("%d",&x);
while(x!=1111){
s=(DNode *)malloc(sizeof(DNode));
s->data = x;// 给新的指针结点赋值e
r->next = s;//将s放在r的下一结点
s->prior = r;//链接
r = s;//r又指向新的表尾结点
scanf("%d",&x);
}
r->next = NULL;
return L;
}
//双链表的插入操作:
bool Addelem(DLinkList &L,int i ,ElemType &e){
int j = 0;
DNode *p,*s;
p = L;
while(p && j<i-1){
p = p->next;
j++;
}
if(!p||(j > i-1)){
printf("insert false");
}
s = (DNode *)malloc(sizeof(DNode));
s->data = e;// 给新的指针结点赋值e
s->next = p->next;//p的后继变成s的后继
p->next->prior = s;
p->next = s;/
s->prior = p;
return true;
//多画图理解过程
}
bool Delete_elem(DLinkList &L,int i,ElemType &e)
{
int j = 0;
DNode *p,*q;
p = L;
while(p && j<i-1){
p = p->next;
j++;
}
if(!p||(j > i-1)){
printf("insert false");
}
e = p->next->data;
q = p->next;
p->next = q->next;
q->next->prior = p;
free(q);
printf("删除的数据为:%d\n",e);
}
//链表的长度
int Length(DLinkList &L){
int len = 0;
DNode *p;
p = L;
while(p->next != NULL){
p = p->next;
len++;
}
return len;
}
//打印表
void printLinkList(DLinkList &L)
{
DNode *p;
p = L->next;
while(p)
{
printf("%d ",p->data);
p = p->next;
}
}
int main(){
DNode *L;
int x,i;
ElemType e;
printf("创建双链表\n");
printf("输入元素:\n");
CreatList(L);
printLinkList(L);
printf("\n");
printf("表长为:%d",Length(L));
printf("\n");
printf("输入插入结点与插入数据:");
scanf("%d%d",&i,&e);
Addelem(L,i,e);
printf("插入后的链表为:\n");
printLinkList(L);
printf("\n");
printf("输入删除结点位置:");
scanf("%d",&i);
Delete_elem(L,i,e);
printf("删除后的链表为:\n");
printLinkList(L);
}