数据结构之双链表----增删改查(C语言)

源代码在博客里可下载,1C币。或者找Q:1286550014要代码

一、导入头文件

#include<stdlib.h>
#include<stdio.h>

二、结构体的定义

//定义一个结构体,用于表示双链表的一个节点
typedef struct node
{
	int data;	//链表中的数据,此例中我们采用整型
	struct node* Next;//本节点指向下一节点的指针
	struct node* Prev;//本节点指向前一节点的指针
}D_list,*PD_list;

//定义一个结构体,将双链表的头指针与尾指针放入,方便操作
typedef struct list
{
	PD_list pHead;
	PD_list pTail;
	int length; //用于表示链表长度
}List,*pList;

三、功能函数的定义

本次双链表共有7个函数:

//每次申请节点都要进行相同的操作,为了减少代码的重复书写,我们定义一个函数
//用于申请一个新节点,并将节点的指针返回
PD_list createNode(int data);

//初始化双链表
void initList(pList p);

//在头结点处插入数据
void insertHead(pList p,int data);

//在尾节点出插入新数据
void insertTail(pList p, int data);

//在指定位置插入节点
void insertIndex(pList p, int index);

//删除指定位置出的节点
void deleteIndex(pList p, int index);

//打印整个双链表内的数据
void showList(pList p);

四、功能函数的依次实现

PD_list createNode(int data)
{
	PD_list pnew = (PD_list)malloc(sizeof(D_list));//申请空间
	pnew->data = data;//以下三句,对新节点进行初始化
	pnew->Next = NULL;
	pnew->Prev = NULL;
	return pnew;//返回新节点指针
}
void initList(pList p)
{
	//将头结点和尾节点都赋值为空,长度为0
	p->pHead = NULL;
	p->pTail = NULL;
	p->length = 0;
}
void insertHead(pList p, int data)
{
	//申请一个新节点
	PD_list pnew = createNode(data);
	if (p->pHead == NULL)//如果头结点为空,说明双链表为空,就将头尾都指向新节点
	{
		p->pHead = pnew;
		p->pTail = pnew;
		p->length++;
	}
	else//如果头节点不为空
	{
		pnew->Next = p->pHead;//先将新节点下一节点指向头结点
		p->pHead->Prev = pnew;//再将头结点前一节点指向新节点
		p->pHead = pnew;//最后将头结点赋值给新节点,头插法完成
		p->length++;
	}
}
void insertTail(pList p, int data)
{
	PD_list pnew = createNode(data);//创建新节点
	if (p->pHead == NULL)//判断双链表是否为空
	{
		p->pHead = pnew;//为空就讲头尾部节点都指向于新节点
		p->pTail = pnew;
		p->length++;//长度加1
	}
	else
	{
		pnew->Prev = p->pTail;//先将新节点的前指针指向原尾节点
		p->pTail->Next = pnew;//再将原尾节点下一节点指针指向于新节点
		p->pTail = pnew;//最后将新节点变为尾节点,功能完成
		p->length++;//长度加1
	}
}
void insertIndex(pList p, int index,int data)
{
	PD_list pnew = createNode(data);//申请一个新节点
	if (index<0 || index>p->length)//判断下标是否有误
	{
		printf("对不起,您输入的位置有误,无法插入!");
		return;
	}
	else
	{
		PD_list ptemp = p->pHead;//定义一个辅助指针,先指向于头部
		for (int i = 0; i < index - 1; ++i)//循环遍历到想要插入节点的前一节点
		{
			ptemp = ptemp->Next;
		}
		//4步连接
		pnew->Next = ptemp->Next;//新节点下一节点指针指向插入位置的下一节点
		pnew->Prev = ptemp;//新节点前一指针指向插入位置的前一节点
		ptemp->Next->Prev = pnew;//新节点下一节点前指针再指向于新节点
		ptemp->Next = pnew;//新节点前节点的下一节点指针指向于新节点
		p->length++;//长度加1
	}
}
void deleteIndex(pList p, int index)
{
	if (index<0 || index>p->length)//判断输入的下标是否有误
	{
		printf("对不起,您输入的位置有误!\n");
		return;
	}
	else
	{
		PD_list ptemp = p->pHead;
		for (int i = 0; i < index; ++i)//遍历循环到想要删除的下标节点处
		{
			ptemp = ptemp->Next;
		}
		//2步完成删除并连接
		ptemp->Prev->Next = ptemp->Next;//删除位置前节点下一节点指向于删除位置节点的下一节点
		ptemp->Next->Prev = ptemp->Prev;//删除位置的下节点前节点指针指向删除位置的前节点
		free(ptemp);//释放掉删除位置处的内存
		p->length--;//长度减1
	}
}
void showList(pList p)
{
	//定义一个辅助指针,用于遍历双链表
	PD_list ptemp = p->pHead;
	while (ptemp->Next)//循环打印
	{
		printf("%d->", ptemp->data);
		ptemp = ptemp->Next;
	}
	printf("%d\n", ptemp->data);
	printf("双链表长度为:%d\n", p->length);
}

五、双链表的使用(main函数)

以下为我的main函数调用,读者可以根据自己的需求调用不用函数
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/83037447