双链表算法库构建

v1.0 : 模仿贺利坚老师, 进行基本构建

贺老师链接:数据结构之自建算法库------双链表_双链表画法-CSDN博客

我的解析博客:双链表的存储结构_p = (*q)->next;-CSDN博客

库函数:

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);
    }

}

运行结果:

相关推荐
ChoSeitaku25 分钟前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
Fuxiao___34 分钟前
不使用递归的决策树生成算法
算法
我爱工作&工作love我39 分钟前
1435:【例题3】曲线 一本通 代替三分
c++·算法
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
workflower1 小时前
数据结构练习题和答案
数据结构·算法·链表·线性回归
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
Sunyanhui11 小时前
力扣 二叉树的直径-543
算法·leetcode·职场和发展
一个不喜欢and不会代码的码农2 小时前
力扣105:从先序和中序序列构造二叉树
数据结构·算法·leetcode
前端郭德纲2 小时前
浏览器是加载ES6模块的?
javascript·算法
SoraLuna2 小时前
「Mac玩转仓颉内测版10」PTA刷题篇1 - L1-001 Hello World
算法·macos·cangjie