一:双向链表头文件
#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct node_t
{
datatype data;//数据域
struct node_t *next;//指向下一个节点的指针 next 下一个
struct node_t *prior;//指向前一个节点的指针 prior 前一个
}link_node_t,*link_list_t;
//将双向链表的头指针和尾指针封装到一个结构体里
//思想上有点像学的链式队列
typedef struct doublelinklist
{
link_list_t head; //指向双向链表的头指针
link_list_t tail; //指向双向链表的尾指针
int len;
}double_node_t,*double_list_t;
//1.创建一个空的双向链表
double_list_t createEmptyDoubleLinkList();
//2.向双向链表的指定位置插入数据 post位置, data数据
int insertIntoDoubleLinkList(double_list_t p, int post, datatype data);
//3.遍历双向链表
void showDoubleLinkList(double_list_t p);
//4.删除双向链表指定位置的数据
int deletePostDoubleLinkList(double_list_t p, int post);
//5.判断双向链表是否为空
int isEmptyDoubleLinkList(double_list_t p);
//6.求双向链表的长度
int lengthDoubleLinkList(double_list_t p);
//7.查找指定数据出现的位置 data被查找的数据
int searchPostDoubleLinkList(double_list_t p,datatype data);
//8.修改指定位置的数据,post修改的位置 data被修改的数据
int changeDataDoubleLinkList(double_list_t p,int post, datatype data);
//9.删除双向链表中的指定数据 data代表删除所有出现的data数据
int deleteDataDoubleLinkList(double_list_t p, datatype data);
二:代码实现
#include "linkstack2.h"
// 1.创建一个空的双向链表
double_list_t createEmptyDoubleLinkList()
{
double_list_t p = (double_list_t)malloc(sizeof(double_node_t));
if (p == NULL)
{
perror("开辟失败:");
return NULL;
}
// 开辟头结点空间
p->len = 0;
p->head = p->tail = (link_list_t)malloc(sizeof(link_node_t));
if (p->head == NULL)
{
perror("开辟失败:");
return NULL;
}
p->head->prior = NULL;
p->head->next = NULL;
return p;
}
// 2.向双向链表的指定位置插入数据 post位置, data数据
int insertIntoDoubleLinkList(double_list_t p, int post, datatype data)
{
link_list_t temp = NULL;
// 容错判断
if (post < 0 || post > p->len)
{
perror("插入失败");
return -1;
}
// 开辟节点存放数据
link_list_t pnew = (link_list_t)malloc(sizeof(link_node_t));
if (pnew == NULL)
{
perror("开辟失败:");
return -1;
}
pnew->data = data;
pnew->prior = NULL;
pnew->next = NULL;
// 将节点插入链表
// 先对插入位置进行判断
if (post == p->len) // 尾插
{
p->tail->next = pnew;
pnew->prior = p->tail;
p->tail = pnew; // 移动尾指针
// printf("000\n");
}
else // 中间插
{
if (post < p->len / 2)
{
temp = p->head;
for (int i = 0; i < post; i++)
temp = temp->next;
}
else
{
temp = p->tail;
for (int i = 0; i < p->len - post - 1; i++)
temp = temp->prior;
}
// 进行插入操作(先练前面,后连后面)
temp->prior->next = pnew;
pnew->prior = temp->prior;
pnew->next = temp;
temp->prior = pnew;
}
// 长度加1
p->len++;
printf("000\n");
return 0;
}
// 3.遍历双向链表
void showDoubleLinkList(double_list_t p)
{
link_list_t temp = p->tail;
while (temp != p->head)
{
printf("%d ", temp->data);
temp = temp->prior;
}
// 正向遍历
// link_list_t temp=p->head;
// while(temp->next!=NULL)
// {
// temp=temp->next;
// printf("%d ",temp->data);
// }
}
// 4.删除双向链表指定位置的数据
int deletePostDoubleLinkList(double_list_t p, int post)
{
link_list_t temp = NULL;
// 容错判断
if (isEmptyDoubleLinkList(p) || post < 0 || post >= p->len)
{
perror("空:");
return -1;
}
// 对删除位置进行判断,两种情况
if (post == p->len - 1) // 尾删
{
// 向前移动尾指针
p->tail = p->tail->prior;
// 释放被删除节点
free(p->tail->next);
p->tail->next = NULL;
}
else // 中间删除
{
if (post < p->len / 2)
{
temp = p->head;
for (int i = 0; i < post; i++)
temp = temp->prior;
}
else
{
temp = p->tail;
for (int i = 0; i < p->len - post-1; i++)
temp = temp->prior;
}
// 进行删除操作(先练前面,后连后面)
temp->prior->next = temp->next;
temp->next->prior = temp->prior;
}
// 长度减1
p->len--;
}
// 5.判断双向链表是否为空
int isEmptyDoubleLinkList(double_list_t p)
{
return p->len == 0;
}
//6.求双向链表的长度
int lengthDoubleLinkList(double_list_t p)
{
return p->len;
}
//7.查找指定数据出现的位置 data被查找的数据
int searchPostDoubleLinkList(double_list_t p,datatype data)
{
link_list_t temp=p->head;
int sum=0;
while(p->head!=NULL)
{
temp=temp->next;
if(temp->data==data)
return sum;
sum++;
}
return -1;
}
//8.修改指定位置的数据,post修改的位置 data被修改的数据
int changeDataDoubleLinkList(double_list_t p,int post, datatype data)
{
if(post<0||post>=p->len||isEmptyDoubleLinkList(p))
{
perror("空");
return -1;
}
link_list_t temp=NULL;
if (post == p->len - 1)
{
p->tail = p->tail->prior;
free(p->tail->next);
p->tail->next = NULL;
}
else
{
if (post < p->len / 2)
{
temp = p->head;
for (int i = 0; i < post; i++)
temp = temp->prior;
}
else
{
temp = p->tail;
for (int i = 0; i < p->len - post-1; i++)
temp = temp->prior;
}
}
temp->data=data;
return 0;
}
//9.删除双向链表中的指定数据 data代表删除所有出现的data数据
int deleteDataDoubleLinkList(double_list_t p, datatype data)
{
link_list_t pdel=NULL;
link_list_t q=p->head->next;
while(p!=NULL)
{
if(p->head->data==data)
{
if(q==p->tail)//尾删
{
p->tail=p->tail->prior;
free(p->tail->next);
p->tail->next=NULL;
q=NULL;
}
else//中间删
{
q->prior->next=q->next;
q->next->prior=q->prior;
pdel=q;
free(pdel);
pdel=NULL;
}
p->len--;
}
else{
q=q->next;
}
}
return 0;
}