v1.0 : 模仿贺利坚老师, 进行基本构建
库函数:
cpp//(1)初始化双链表 void InitDoubleLinkList(DoubleLinkList *&L); //(2)输出双链表 void Dispaly_DoubleLinkList(DoubleLinkList *L); //(3)双链表头插法建表 void CreateDoubleLinkList_Head(DoubleLinkList *&L,ElemType Array_used[],int Array_size); //(4)双链表尾插法建表 void CreateDoubleLinkList_Tail(DoubleLinkList *&L,ElemType Array_used[],int Array_size); //(5)销毁双链表 void DestroyDoubleLinkList(DoubleLinkList *&L); //(6)判断双链表是否为空 bool DoubleLinkList_Empty(DoubleLinkList *L); //(7)求双链表长度 int DoubleLinkList_Length(DoubleLinkList *L); //(8) 获取双链表特定位置的节点值 bool GetDoubleLinkListLocate_value(DoubleLinkList *L, int specific_locate, ElemType &value); //(9) 查找一个特定值的节点,并返回其位置 int FindDoubleLinkListValue_Location(DoubleLinkList *L, ElemType specific_value); //(10) 插入一个节点到双链表的特定位置 bool Insert_DoubleLinkList(DoubleLinkList *&L, int specific_location, ElemType insert_value); //(11) 删除双链表的特定位置的节点,并取其值 bool Delete_DoubleLinkList_Locate(DoubleLinkList *&L, int specific_locate, ElemType &delete_value);
根据所需进行使用
源文件如下:
DoubleLinkList.h
cpp
#ifndef DOUBLELINKLIST_H_INCLUDED
#define DOUBLELINKLIST_H_INCLUDED
typedef int ElemType;
typedef struct DoubleNode
{
ElemType data;
struct DoubleNode *prior;
struct DoubleNode *next;
}DoubleLinkList;
//(1)初始化双链表
void InitDoubleLinkList(DoubleLinkList *&L);
//(2)输出双链表
void Dispaly_DoubleLinkList(DoubleLinkList *L);
//(3)双链表头插法建表
void CreateDoubleLinkList_Head(DoubleLinkList *&L,ElemType Array_used[],int Array_size);
//(4)双链表尾插法建表
void CreateDoubleLinkList_Tail(DoubleLinkList *&L,ElemType Array_used[],int Array_size);
//(5)销毁双链表
void DestroyDoubleLinkList(DoubleLinkList *&L);
//(6)判断双链表是否为空
bool DoubleLinkList_Empty(DoubleLinkList *L);
//(7)求双链表长度
int DoubleLinkList_Length(DoubleLinkList *L);
//(8) 获取双链表特定位置的节点值
bool GetDoubleLinkListLocate_value(DoubleLinkList *L, int specific_locate, ElemType &value);
//(9) 查找一个特定值的节点,并返回其位置
int FindDoubleLinkListValue_Location(DoubleLinkList *L, ElemType specific_value);
//(10) 插入一个节点到双链表的特定位置
bool Insert_DoubleLinkList(DoubleLinkList *&L, int specific_location, ElemType insert_value);
//(11) 删除双链表的特定位置的节点,并取其值
bool Delete_DoubleLinkList_Locate(DoubleLinkList *&L, int specific_locate, ElemType &delete_value);
#endif // DOUBLELINKLIST_H_INCLUDED
DoubleLinkList.cpp
cpp
#include "DoubleLinkList.h"
#include "malloc.h"
#include "stdio.h"
/*****************************************
功 能: 双链表库函数
编程人: 王涛
时 间: 2024.4.1
版 本: V1.0
******************************************/
/**************************************************
(1)函数名: InitDoubleLinkList
功 能: 初始化双链表
参 数: ①DoubleLinkList *&L: 要进行初始化的双链表
返回值: 无
**************************************************/
void InitDoubleLinkList(DoubleLinkList *&L)
{
L = (DoubleLinkList*)malloc(sizeof(DoubleLinkList));
L->prior = NULL;
L->next = NULL;
}
/**************************************************
(2)函数名: Dispaly_DoubleLinkList
功 能: 输出展示双链表
参 数: DoubleLinkList *L:要展示的双链表
注意: ① 这里是 刷一下存在感
返回值: 无
**************************************************/
void Dispaly_DoubleLinkList(DoubleLinkList *L)
{
DoubleLinkList *showNode = L->next;
if(L->next == NULL) //①
{
printf("Hey, this is empty!");
}
while(showNode != NULL)
{
printf("%d",showNode->data);
printf(" ");
showNode = showNode->next;
}
printf("\n");
}
/**************************************************
(3)函数名:CreateDoubleLinkList_Head
功 能: 双链表头插法建表
参 数: ①DoubleLinkList *&L:要建立在的链表上
②ElemType Array_used[]: 要使用的数组
③int Array_size : 数组的大小
返回值: void
**************************************************/
void CreateDoubleLinkList_Head(DoubleLinkList *&L,ElemType Array_used[],int Array_size)
{
DoubleLinkList *newNode;
L= (DoubleLinkList *)malloc(sizeof(DoubleLinkList));
L->prior = NULL;
L->next = NULL;
//遍历数组,创建新节点,进而头插法插入
for(int i = 0; i < Array_size; i++)
{
newNode = (DoubleLinkList*)malloc(sizeof(DoubleLinkList));
newNode->data = Array_used[i];
newNode->next = L->next;
if(L->next != NULL)//L->next的前驱是否需操作
{
L->next->prior = newNode;
}
L->next = newNode;
newNode->prior = L;
}
}
/**************************************************
(4)函数名:CreateDoubleLinkList_Tail
功 能: 双链表尾插法建表
参 数: ①DoubleLinkList *&L:要建立在的链表上
②ElemType Array_used[]: 要使用的数组
③int Array_size : 数组的大小
返回值: void
**************************************************/
void CreateDoubleLinkList_Tail(DoubleLinkList *&L,ElemType Array_used[],int Array_size)
{
DoubleLinkList *newNode,*tailNode;
L = (DoubleLinkList*)malloc(sizeof(DoubleLinkList));
tailNode = L;
for(int i = 0; i < Array_size; i++)
{
newNode = (DoubleLinkList*)malloc(sizeof(DoubleLinkList));
newNode->data = Array_used[i];
tailNode->next = newNode;
newNode->prior = tailNode;
tailNode = newNode;
}
tailNode->next = NULL;
}
/**************************************************
(5)函数名: DestroyDoubleLinkList
功 能: 销毁双链表
参 数: DoubleLinkList *&L:将要销毁的双链表
注 意: ①避免销毁后的L变成的野指针, 再次被误用时, 指针飘飞
返回值: 无
**************************************************/
void DestroyDoubleLinkList(DoubleLinkList *&L)
{
DoubleLinkList *freeNode;
DoubleLinkList *backNode;
freeNode = L;
backNode = freeNode->next;
while(backNode != NULL)
{
free(freeNode);
freeNode = backNode;
backNode = freeNode->next;
}
free(freeNode);
L->next = NULL; //①
}
/**************************************************
(6)函数名: DoubleLinkList_Empty
功 能: 判断双链表是否为空
参 数: DoubleLinkList *L:要判断的双链表
返回值: bool: 是否为空? true:false
**************************************************/
bool DoubleLinkList_Empty(DoubleLinkList *L)
{
return (L->next == NULL);
}
/**************************************************
函数名: DoubleLinkList_Length
功 能: 求双链表数据节点长度
参 数: DoubleLinkList *L:要计算的双链表
返回值: int : 节点长度(数据节点,头结点不算)
**************************************************/
int DoubleLinkList_Length(DoubleLinkList *L)
{
int nowLength = 0;
DoubleLinkList *visit_Node = L;
while(visit_Node->next != NULL)
{
nowLength++;
visit_Node = visit_Node->next;
if(nowLength > 1000)
{
return -1;
}
}
return (nowLength);
}
/**************************************************
函数名: GetDoubleLinkListLocate_value
功 能: 获取双链表特定位置的节点值
参 数: (1)DoubleLinkList *L: 要遍历的双链表
(2)int specific_locate: 特定的位置
(3)ElemType &value: 回调存储节点值
返回值: bool:是否获得所需位置的节点值? true:false
**************************************************/
bool GetDoubleLinkListLocate_value(DoubleLinkList *L, int specific_locate, ElemType &value)
{
int nowLocate = 0;
DoubleLinkList *nowNode = L;
while(nowLocate < specific_locate && nowNode != NULL)
{
nowLocate++;
nowNode = nowNode->next;
}
if(nowNode == NULL)
{
return false;
}
else
{
value = nowNode->data;
return true;
}
}
/**************************************************
函数名:FindDoubleLinkListValue_Location
功 能: 查找一个特定值的节点,并返回其位置
参 数:(1)DoubleLinkList *L: 查找的双链表
(2)ElemType specific_value: 需要查找的特定值
返回值: int : 特定的位置(0: 没找到 , 大于0:找到)
**************************************************/
int FindDoubleLinkListValue_Location(DoubleLinkList *L, ElemType specific_value)
{
int nowLocate = 1;
DoubleLinkList *nowNode = L->next;
while(nowNode != NULL && nowNode->data != specific_value)
{
nowLocate++;
nowNode = nowNode->next;
}
if(nowNode == NULL)
{
return 0;
}
else
{
return nowLocate;
}
}
/**************************************************
函数名: Insert_DoubleLinkList
功 能: 插入一个节点到双链表的特定位置
参 数: (1)DoubleLinkList *&L:要插到的双链表
(2)int specific_location: 要插入的位置
(3)ElemType insert_value: 要插入的新节点的值
返回值: bool: 是否找到特定位置,并插入? true找到:false没找到
**************************************************/
bool Insert_DoubleLinkList(DoubleLinkList *&L, int specific_location, ElemType insert_value)
{
int nowLocate = 0;
DoubleLinkList *nowNode = L;
DoubleLinkList *newNode;
//找到第 specific_location-1个位置,把节点插其后
while(nowLocate < (specific_location - 1) && nowNode != NULL)
{
nowLocate++;
nowNode = nowNode->next;
}
if(nowNode == NULL)//未找到第specific_location-1个位置
{
return false;
}
else //找到此位置,插入
{
newNode = (DoubleLinkList*)malloc(sizeof(DoubleLinkList));
newNode->data = insert_value;
//双链表节点插入
newNode->next = nowNode->next;
//找到第specific_location-1个位置,但其后面不一定存在节点
if(nowNode->next != NULL)
{
nowNode->next->prior = newNode;
}
nowNode->next = newNode;
newNode->prior = nowNode;
return true;
}
}
/**************************************************
函数名: Delete_DoubleLinkList_Locate
功 能: 删除双链表的特定位置的节点,并取其值
参 数: (1)DoubleLinkList *&L:要删除的双链表
(2)int specific_locate: 要删除的特定位置
(3)ElemType &delete_value: 回调已经删除的节点的值
注 意 : ①由于是双链表, 我们要找的位置是specific_locate -1
②判断specific_locate -1位置节点是否存在
不仅仅需要找到(specific_locate -1), 我们还需要判断specific_locate位置节点是否存在
返回值: bool:是否找到特定位置,并删除? true:false
**************************************************/
bool Delete_DoubleLinkList_Locate(DoubleLinkList *&L, int specific_locate, ElemType &delete_value)
{
int nowLocate = 0;
DoubleLinkList *nowNode = L;
DoubleLinkList *deleteNode;
while(nowLocate < (specific_locate-1) && nowNode != NULL)//①
{
nowLocate++;
nowNode = nowNode->next;
}
//②判断specific_locate -1和specific_locate位置节点是否存在
if(nowNode == NULL || nowNode->next == NULL)
{
return false;
}
else
{
deleteNode = nowNode->next;
delete_value = deleteNode->data;
nowNode->next = deleteNode->next;//链接后续节点,从链表中删除deleteNode
if(nowNode->next != NULL) //判断是否需要管后继节点的前驱指针
{
nowNode->next->prior = nowNode;
}
free(deleteNode);
return true;
}
}
主函数调用
main.cpp
cpp
#include <stdio.h>
#include "DoubleLinkList.h"
int main()
{
DoubleLinkList *A,*B;
ElemType elem;
ElemType a[] = {1,2,3,4,5,6,7,8};
CreateDoubleLinkList_Head(B,a,8);
Dispaly_DoubleLinkList(B);
if(GetDoubleLinkListLocate_value(B,3,elem))
{
printf("B的第3个元素是%d\n",elem);
}
printf("3在B中是第%d个元素\n",FindDoubleLinkListValue_Location(B,3));
if(Insert_DoubleLinkList(B,5, 100))
{
printf("插入成功了");
Dispaly_DoubleLinkList(B);
}
if(Delete_DoubleLinkList_Locate(B, 5, elem))
{
printf("成功删除了B中的第5个元素%d\n",elem);
Dispaly_DoubleLinkList(B);
}
}
运行结果: