代码如下:
#include <stdio.h>
#include <stdlib.h>
// 声明双链表的结构体
struct DLNode {
int data;
struct DLNode *prior;
struct DLNode *next;
};
/* 创建一个双链表(使用尾插法) */
/* *&L指的是要创建的单链表;a[]指的是要批量添加的整数数组;n指的是数组长度 */
void createDlistR(DLNode *&L,int a[],int n) {
DLNode *temp,*node;
L=(DLNode *)malloc(sizeof(DLNode));
L->prior=NULL;
L->next=NULL;
temp=L;
for(int i=0; i<n; i++) {
node=(DLNode *)malloc(sizeof(DLNode));
node->data=a[i];
/* 下面3句将node插入到L的尾部,并且temp指向node,node->prior=temp;这一句是和建立单链表不同的地方 */
temp->next=node;
node->prior=temp;
temp=node;
}
temp->next=NULL;
}
/* 打印双链表 */
/* *list指的是要被打印的双链表 */
void printList(DLNode *list) {
printf("\n");
while(list->next!=NULL) {
printf("%d\t",list->next->data);
list=list->next;
}
printf("\n");
}
/* 求双链表的表长的算法 */
/* *list指的是双链表 */
int length(DLNode *list) {
DLNode *temp=list->next;// 临时指针变量
int i=0; // 计数器,用来统计表长,初始长度为0
while(temp!=NULL) { // 循环条件,当单链表中结点不为NULL
temp=temp->next; // 指向下一个结点
i++; // 计数器加1
}
return i;
}
/* 通过值查找结点的算法 */
/* *list指的是双链表;x指的是要查找的值 */
DLNode * findNode(DLNode *list,int x) {
// 在双链表中查找第一个值为x的结点,从第一个结点开始,边扫描边比较,若找到这样的则返回结点指针,否则返回NULL
DLNode *temp=list->next;// 获取双链表的第一个结点(不是头结点)
while(temp!=NULL) { // 循环遍历
if(temp->data==x) { // 查找到值后跳出while循环
break;
}
temp=temp->next; // 到下一个结点
}
return temp; // 返回查找到的结点指针
}
/* 通过序号(不是下标)查找结点的算法 */
/* *list指的是双链表;p指的是要查找的序号 */
DLNode * find(DLNode *list,int p) {
DLNode *temp;
temp=list->next;
int i=1;
while(temp!=NULL&&i<p) {
i++;
temp=temp->next;
}
if(i==p) {
return temp;
} else {
return NULL;
}
}
/* 在双链表中的指定位置插入一个新结点 */
/* *&list指的是要被操作的双链表;pos指的是要插入的序号位置(不是下标);data指的是结点数据 */
void insert(DLNode *&list,int pos,int data) {
DLNode *priorNode,*node,*temp;
temp=list->next;
/* 分情况讨论:(1)插入位置是首位;(2)插入位置不是首位 */
/* (1)插入位置是首位 */
if(pos==1) {
node=(DLNode *)malloc(sizeof(DLNode)); // 创建新结点
node->data=data; // 设置新结点的数据
/* 双链表插入结点的核心代码start */
node->next=temp;
temp->prior=node;
list->next=node;
node->prior=list;
/* 双链表插入结点的核心代码end */
return;
}
priorNode=find(list,pos-1); // 获取要插入位置的前一个结点指针
if(priorNode==NULL) {
printf("第%d个结点不存在!",pos-1);
} else if(priorNode->next==NULL) {
printf("第%d个结点不存在!",pos);
} else {
node=(DLNode *)malloc(sizeof(DLNode));
node->data=data;
node->next=priorNode->next;
priorNode->next->prior=node;
node->prior=priorNode;
priorNode->next=node;
}
}
/* 删除双链表中指定序号位置(不是下标)的结点元素 */
/* *&list指的是要进行操作的双链表;pos指的是要删除的序号位置 */
void deleteNode(DLNode *&list,int pos) {
DLNode *temp,*priorNode,*tempDelNode;
temp=list->next;
/* 分情况讨论:(1)删除序号位置是首位 ;(2)删除序号位置是首位 */
/* (1)删除序号位置是首位 ; */
if(pos==1) {
/* 双链表删除结点的核心代码start */
tempDelNode=temp;
tempDelNode->next->prior=list;
list->next=tempDelNode->next;
free(tempDelNode);
/* 双链表删除结点的核心代码end */
return;
}
/* (2)删除序号位置是首位 */
priorNode=find(list,pos-1); // 获取要被删除结点的前一个结点的指针
if(priorNode==NULL) {
printf("第%d个结点不存在!",pos-1);
} else if(priorNode->next==NULL) {
printf("第%d个结点不存在!",pos);
} else {
tempDelNode=priorNode->next;
tempDelNode->next->prior=priorNode;
priorNode->next=tempDelNode->next;
free(tempDelNode);
}
}
int main() {
DLNode *list,*t1,*t2;
/* [0.]创建初始测试双链表 */
int a[]= {1,3,5,7,9}; // 要批量插入到双链表中的结点元素
createDlistR(list,a,5); // 创建一个双链表(带头结点),其中有些元素
/* [1.]打印双链表 */
printList(list);
/* [2.]双链表的长度 */
printf("\n%d\n",length(list)); // 打印双链表的长度
/* [3.]查找结点 */
t1=findNode(list,7); // 在双链表中查找data值为7的结点
printf("\n%d\n",t1->data); // 打印查找到结点的data值
/* [4.]按序号查找结点 */
t2=find(list,3); // 在双链表中查找序号位置为3的结点
printf("\n%d\n",t2->data); // 打印查找到的结点的data
/* [5.]插入新结点 */
insert(list,1,99); // 在序号位置为1的地方插入一个data值为99的新结点
printList(list); // 打印插入后的双链表
/* [6.]删除结点 */
deleteNode(list,1); // 删除双链表中序号位置为1的结点
printList(list); // 打印删除后的双链表
return 0;
}
代码运行结果如下: