嵌入式学习的第二十一天-数据结构-双向链表

一、双向链表

1.定义

双向链表是在单链表的每个结点中,再设置一个指向其钱去节点的指针域。

复制代码
typedef struct DulNode
{
    ElemType date;
    struct DulNode *pri;//直接前驱指针
    sturct DulNode *next;//直接后继指针
}DulNode,*DuLinkList;

2.双向链表的创建

复制代码
struct DouLinkList* CreateDouLinkList() 
{
    struct DouLinkList*dl = malloc(sizeof(struct DouLinkList));
    if(NULL == dl)
    {
        fprintf(stderr, "CreatDouLinkList malloc");
        return NULL;
    }  
    dl->head =NULL;
    dl->clen = 0;
    return dl;  
}

3.双向链表的插入

(1)头插

复制代码
int InsertHeadDouLinkList(struct DouLinkList*dl,struct DATATYPE*data)
{
    struct DouNode*newnode = malloc(sizeof( struct DouNode));
    if(NULL == newnode)
    {
       fprintf(stderr, "InsertHeadDouLinkList malloc");
        return 1; 
    }

    memcpy(&newnode->data,data,sizeof(struct DATATYPE));
    newnode->next = NULL;
    newnode->prev = NULL;

    newnode->next =dl->head;
    if(dl->head)
    {
        dl->head->prev =newnode;
    }
    dl->head = newnode;
    dl->clen++;
    return 0;
}

(2)尾插

复制代码
int InsertTailDouLinkList(struct DouLinkList*dl,struct DATATYPE*data)
{
    if(IsEmptyDouLinkList(dl))
    {
        return InsertHeadDouLinkList(dl,data);
    }
    else
    {   
        struct DouNode*tmp = dl->head;
        while(tmp->next)
        {
            tmp = tmp->next;
        }

        struct DouNode*newnode = malloc(sizeof( struct DouNode));
        if(NULL == newnode)
         {
             fprintf(stderr, "InsertTailDouLinkList malloc");
             return 1; 
         }
        //初始化节点
        memcpy(&newnode->data,data,sizeof(struct DATATYPE));
        newnode->next = NULL;
        newnode->prev = NULL;
        //连接链表
        newnode->prev = tmp;
        tmp->next = newnode;
        dl->clen++;
    }
    return 0;
}

(3) 任意位置插

复制代码
int InsertPosDouLinkList(struct DouLinkList*dl,struct DATATYPE*data,int pos)
{
    int len = GetSizeDouLinkList(dl);
    if(pos<0||pos>len)
    {
        return 1;
    }
    if(0 == pos)
    {
        return InsertHeadDouLinkList(dl,data);
    }
    else if(pos == len)
    {
        return InsertTailDouLinkList(dl, data);
    }
    else
    {
        struct DouNode*newnode = malloc(sizeof( struct DouNode));
        if(NULL == newnode)
         {
             fprintf(stderr, "InsertPosDouLinkList malloc");
             return 1; 
         }
        //初始化节点
        memcpy(&newnode->data,data,sizeof(struct DATATYPE));
        newnode->next = NULL;
        newnode->prev = NULL;
        struct DouNode*tmp = dl->head;
        int i = 0;
        for(i = 0;i < pos;++i)
        {
            tmp = tmp->next;
        }
        newnode->next=tmp;
        newnode->prev=tmp->prev;
        tmp->prev=newnode;
        newnode->prev->next=newnode;
    }
    return 0;
}

4.双向链表的遍历

复制代码
int ShowDouLinkList(struct DouLinkList*dl,DIR dir)
{
    struct DouNode*tmp = dl->head;
    if(FORWADR == dir)
    {
       while (tmp)
       {
        printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
        tmp=tmp->next;
       }
       
    }
    else if(BACKWADR == dir)
    {
        while(tmp->next)
        {
            tmp=tmp->next;
        }
        while(tmp)
        {
            printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
            tmp =tmp->prev;
        }
    }
    return 0;
}
  1. vi Makefile(工程管理工具) :三个.c以上可使用

方法一:

复制代码
a.out(目标):main.c ./doulink (依赖)
    gcc main.c doulink.c//前面空一个Tab键
clean:
    rm a.out

在终端敲make,进行编译,若要指定makefile ,加-f再加指定makefile

方法二:

复制代码
#代表源文件
SRC += main.c(变量名任取)//指定变量
SRC += doulink.c
DST = app(可执行文件)

CC = gcc//编译器
FLAG = -g
LIB = -lm

$(DST):$(SRC)
    $(CC) $(SRC) $(FLAG) $(LIB)-o(指定名字) $(DST)
clean:
    rm $(DST)

6.双向链表的查找

复制代码
struct DouNode * FindDouLinkList(struct DouLinkList*dl,char*name)
{
    if(IsEmptyDouLinkList(dl))
    {
        return NULL;
    }
    struct DouNode*tmp = dl->head;
    while(tmp)
    {
        if(0 == strcmp(tmp->data.name,name))
        {
            return tmp;
        }
        tmp = tmp->next;
    }
    return NULL;
}

7.双向链表的修改

复制代码
int ModifyDouLinkList(struct DouLinkList*dl,char*name,struct DATATYPE*data)
{
    struct DouNode*tmp = FindDouLinkList(dl, name);
    if(NULL == tmp)
    {
        return 1;
    }
    memcpy(&tmp->data, data,sizeof(struct DATATYPE));
    return 0;
}

8.双向链表的销毁

复制代码
int DestoryDouLinkList(struct DouLinkList*dl)
{
    while(1)
    {
        struct DouNode*tmp = dl->head;
        if(NULL == tmp)
        {
            break;
        }
        dl->head = dl->head->next;
        free(tmp);
    }
    free(dl);
    dl = NULL;

    return 0;
}

9.双向链表的删除

复制代码
int DeleteDouLinkList(struct DouLinkList*dl,char*name)
{
    if(IsEmptyDouLinkList(dl))
    {
        return 1;
    }
    struct DouNode*tmp = FindDouLinkList(dl, name);
    if(tmp ==dl->head)
    {
        dl->head =dl->head->next;
        tmp->next->prev = NULL;
        free(tmp);
    }
    else if(NULL == tmp->next)
    {
        tmp->prev->next = NULL;
        free(tmp);
    }
    else
    {
        tmp->next->prev = tmp->prev;
        tmp->prev->next = tmp->next;
        free(tmp);
    }
    dl->clen--;
    return 0;
}

10.双向链表的逆序

复制代码
int ReverseDouLinkList(struct DouLinkList*dl)
 {
    struct DouNode*prev = NULL;
    struct DouNode*tmp = dl->head;
    struct DouNode*next = tmp->next;
    int len = GetSizeDouLinkList(dl);
    if(len < 2)
    {
        return 1;
    }
    while(1)
    {
        tmp->next = prev;
        tmp->prev = next;
        prev = tmp;
        tmp = next;
        if(NULL == tmp)
        {
            break;
        }
        else
        {
            next = next->next;
        }
    }
    dl->head = prev;
    return 0;
 }
相关推荐
悠哉悠哉愿意12 分钟前
【数学建模学习笔记】机器学习分类:KNN分类
学习·机器学习·数学建模
四谎真好看18 分钟前
Java 学习笔记(进阶篇2)
java·笔记·学习
程序猿炎义27 分钟前
【NVIDIA AIQ】自定义函数实践
人工智能·python·学习
小陈phd40 分钟前
高级RAG策略学习(四)——上下文窗口增强检索RAG
人工智能·学习·langchain
Jayyih2 小时前
嵌入式系统学习DAY28(网络编程)
网络·学习·tcp/ip
dbdr09012 小时前
Linux 入门到精通,真的不用背命令!零基础小白靠「场景化学习法」,3 个月拿下运维 offer,第二十六天
linux·运维·服务器·网络·python·学习
大白的编程日记.3 小时前
【Linux学习笔记】信号的深入理解之软件条件产生信号
linux·笔记·学习
buyutang_3 小时前
C/C++ Linux系统编程:线程控制详解,从线程创建到线程终止
linux·c语言·c++·学习
yzx9910133 小时前
图像去雾:从暗通道先验到可学习融合——一份可跑的 PyTorch 教程
人工智能·pytorch·学习
练习时长两年半的Java练习生(升级中)4 小时前
从0开始学习Java+AI知识点总结-30.前端web开发(JS+Vue+Ajax)
前端·javascript·vue.js·学习·web