头文件:list.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
/*
声明双链表节点元素
*/
typedef struct LIST_NODE
{
int value;
struct LIST_NODE *per;//向前指针
struct LIST_NODE *next;//向后指针
}node;
/*
声明 双链表头尾结构
*/
typedef struct LinkNode
{
node* head;//指向头部
node* tail;//指向尾部
}List;
//初始化链表
void init(List *pList);
//头部插入数据
void addOfHead(List* pList, int value);
//尾部插入数据
void addOfBack(List* pList, int value);
//正序输出
void showPositive(List* pList);
//逆序输出
void showReversed(List* pList);
//正序查找
node *findPositive(List* pList,int data);
//逆序查找
node *findReversed(List* pList,int data);
//插入数据
void insertData(List* pList, int value, int newValue);
//删除数据
void deleteData(List* pList, int value);
头文件函数实现:list.c
#include"list.h"
//初始化链表
void init(List* pList)
{
/*
头尾指针初始化NULL
*/
pList->head=pList->tail = NULL;
}
//头部插入数据
void addOfHead(List* pList, int value)
{
//创建节点
node* pNewNode = malloc(sizeof(node));
if (pNewNode != NULL)
{
pNewNode->value = value;
pNewNode->per = NULL;
pNewNode->next = NULL;
if (pList->head == NULL || pList->tail == NULL)//没有节点
{
pList->head = pNewNode;
pList->tail = pNewNode;
}
else//有节点
{
pList->head->per = pNewNode;//前 原理的前节点指向新节点
pNewNode->next = pList->head;//后 新节点的后节点指向原理的头节点
pList->head = pNewNode;//改变头指针 指向新节点
}
}
}
//尾部插入数据
void addOfBack(List* pList, int value)
{
//创建节点
node* pNewNode = malloc(sizeof(node));
if (pNewNode != NULL)
{
pNewNode->value = value;
pNewNode->per = NULL;
pNewNode->next = NULL;
if (pList->head == NULL || pList->tail == NULL)//没有节点
{
pList->head = pNewNode;
pList->tail = pNewNode;
}
else//有节点
{
pList->tail->next = pNewNode;//前 原理的后节点指向新节点
pNewNode->per = pList->tail;//后 新节点的前节点指向原理的尾节点
pList->tail = pNewNode;//改变尾指针 指向新节点
}
}
}
//正序输出
void showPositive(List* pList)
{
node* p = pList->head;//指向链表结构头节点
while (p!=NULL)
{
printf("%3d", p->value);
p = p->next;//后指针递增
}
printf("\n");
}
//逆序输出
void showReversed(List* pList)
{
node* p = pList->tail;//指向链表结构尾节点
while (p != NULL)
{
printf("%3d", p->value);
p = p->per;//前指针递增
}
printf("\n");
}
//正序查找
node* findPositive(List* pList, int data)
{
node* pNode = pList->head;//指向链表结构尾节点
while (pNode != NULL)
{
if (pNode->value == data)
{
return pNode;
}
pNode = pNode->next;//后指针递增
}
return NULL;
}
//逆序查找
node* findReversed(List* pList, int data)
{
node* pNode = pList->tail;//指向链表结构尾节点
while (pNode != NULL)
{
if (pNode->value == data)
{
return pNode;
}
pNode = pNode->per;//前指针递增
}
return NULL;
}
/*
插入数据 insertData
参数: List* pList 链表
int value 要插入数据的毗邻数据值,确定插入位置,如果 value 在中间则插入其前,若是头部,则插入插入头 部,若是尾部,则插入尾部
int newValue 要插入的新节点的值
*/
void insertData(List* pList, int value,int newValue)
{
node* pNewNode = malloc(sizeof(node));
if (pNewNode != NULL)
{
pNewNode->value = newValue;
pNewNode->per = NULL;
pNewNode->next = NULL;
//查找元素
node* p = NULL;
p = pList->head;
while (p != NULL)
{
if (p->value == value)
{
break;//找到匹配的值,跳出循环
}
else
{
p = p->next;//指针向前递增
}
}
//p存储了匹配值的指针
if (p != NULL)
{
if (p != pList->head || p == pList->tail)//匹配在链表中间或尾部,在匹配元素的前面插入
{
pNewNode->next = p; //向后指针 指向匹配的元素
pNewNode->per = p->per;//向前指针 指向匹配元素的 向前指针
p->per->next = pNewNode;//p->per->next 匹配元素的 前一个元素的 向后指针 ,指向新节点
p->per = pNewNode;//匹配元素的 向前指针 指向新节点
}
else if (p == pList->head)//匹配在链表头部,在匹配元素的前面插入
{
p->per = pNewNode;//匹配元素的 向前指针 指向新节点
pNewNode->next = p;
pList->head = pNewNode;
}
}
}
}
//删除数据
void deleteData(List* pList, int value)
{
node* p = NULL;
p = pList->head;
while (p!=NULL)
{
if (p->value == value)
{
break;//找到匹配的值,跳出循环
}
else
{
p = p->next;//指针向前递增
}
}
//p存储了匹配值的指针
if (p != NULL)
{
if (p != pList->head && p != pList->tail)//匹配在链表中间
{
p->per->next = p->next;//p->per->next 代表当前匹配元素的前一个元素 让 当前匹配元素的前指针 存储的对象的 后指针 指向 当前匹配元素的后指针 (链表连接跳过当前元素)
p->next->per = p->per;//p->next->per 代表当前匹配元素的后一个元素 改变前 指向
free(p);//释放
}
else if(p==pList->head)//匹配在链表头部
{
pList->head = p->next;//改变头节点的指向
p->next->per = NULL;//p->next 代表当前匹配元素的下一个元素
free(p);
}
else if(p==pList->tail)//匹配在链表尾部
{
pList->tail = p->per; //改变尾节点指向 指向当前匹配元素的前指针
p->per->next = NULL;//p->per 代表当前匹配元素的前一个元素
free(p);
}
}
}
主函数测试调用:
#include"list.h"
void main()
{
List list;
init(&list);//初始化
addOfHead(&list, 1);//添加元素
addOfHead(&list, 2);
addOfHead(&list, 3);
addOfHead(&list, 4);
addOfHead(&list, 5);
showPositive(&list);//输出
insertData(&list, 2, 33);//插入元素
printf("\n\n");
showPositive(&list);
printf("\n\n");
deleteData(&list, 3);//删除前,需要先判断是否有数据
node* pNode1= findPositive(&list, 4);//查找元素
if (pNode1 != NULL)
{
pNode1->value = 40;
}
node* pNode2=findReversed(&list, 40);//查找元素
if (pNode2 != NULL)
{
pNode2->value = 44;
}
showReversed(&list);
system("pause");
}
双链表结构图:
头部插入:
尾部插入:
删除匹配节点: