自学嵌入式 day21 - 数据结构 双向链表

1.双向链表

2.基础操作

(1)头部插入

int InsertHeadDouLinkList(DouLinkList *dl,DATATYPE *data)

{

DouLinkNode *newnode = (DouLinkNode *)malloc(sizeof(DouLinkNode));//定义新节点来存储需插入的数据

if(NULL == newnode)//判断结点空间是否申请成功

{

fprintf(stderr,"intertHeadDouLinkList malloc");

return 1;

}

memcpy(&newnode -> data,data,sizeof(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 ShowDouLinkList(DouLinkList *dl,DIR dir)

{

if(FORWADR == dir)//正向打印

{

DouLinkNode *tmp = dl -> head;

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)//反向打印,从末尾开始向前打印

{

DouLinkNode *tmp = dl -> head;

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;

}

}

}

(3)尾部插入

int IsEmptyLinkList(DouLinkList *dl)

{

return 0 == dl -> clen;

}

int InsertTaiDouLinkList(DouLinkList *dl,DATATYPE *data)

{

if(IsEmptyLinkList(dl))//判断链表是否为空

{

return InsertHeadDouLinkList(dl,data);

}

else

{

DouLinkNode *newnode = malloc(sizeof(DouLinkNode));//申请新结点存储待插入数据

if(NULL == newnode)//判断新结点空间是否申请成功

{

fprintf(stderr,"insertTaiDouLinkList malloc\n");

return 1;

}

memcpy(&newnode -> data,data,sizeof(DATATYPE));//存入待插入数据

newnode -> next = NULL;//初始化新结点指针

newnode -> prev = NULL;

DouLinkNode *tmp = dl -> head;//定义新指针,指向头指针

while(tmp -> next)//遍历链表

{

tmp = tmp -> next;

}

newnode -> prev = tmp;//将新结点插入链表尾部

tmp -> next = newnode;

dl -> clen++;

}

return 0;

}

(4)指定位置插入

int GetsizeofDouLinkList(DouLinkList *dl)

{

return dl -> clen;

}

int InsertPosDouLinkList(DouLinkList *dl,DATATYPE *data,int pos)

{

int len = GetsizeofDouLinkList(dl);//算出链表长度

if(0 == pos)//头部插入

{

return InsertHeadDouLinkList(dl,data);

}

else if(pos == len)//尾部插入

{

return InsertTaiDouLinkList(dl,data);

}

else

{

DouLinkNode *newnode = malloc(sizeof(DouLinkNode));

if(NULL == newnode)

{

fprintf(stderr,"InsertPosDouLinkList malloc\n");

return 1;

}

memcpy(&newnode -> data,data,sizeof(DATATYPE));

newnode -> next = NULL;

newnode -> prev = NULL;

DouLinkNode *tmp = dl -> head;

for(int i = 0;i < pos;++i)//遍历链表,定位待插位置

{

tmp = tmp -> next;

}

newnode -> next = tmp;//将新结点和待插位置的前结点和后结点连接

newnode -> prev = tmp -> prev;

tmp -> prev = newnode;

newnode -> prev ->next = newnode;

dl ->clen++;

}

return 0;

}

(5)查找

DouLinkNode *FindDouLinkList(DouLinkList *dl,char *name)

{

int len = GetsizeofDouLinkList(dl);//获取链表长度

DouLinkNode *tmp = dl -> head;//定义新指针,指向头指针

for(int i = 0;i < len;++i)//遍历链表

{

if(0 == strcmp(tmp -> data.name,name))//用已给name查找结点

{

return tmp;

}

tmp = tmp -> next;

}

return NULL;

}

(6)替换

int ModifyDouLinkLinst(DouLinkList *dl,char *name,DATATYPE *data)

{

DouLinkNode *ret = FindDouLinkList(dl,name);//查找结点

if(NULL == ret)//判断是否找到结点

{

return 1;

}

memcpy(&ret -> data,data,sizeof(DATATYPE));//替换数据

return 0;

}

练习:

(1)销毁

int DestroyDouLinkList(struct DouLinkList* dl)

{

DouLinkNode *tmp = dl -> head;//定义新指针,指向头指针

DouLinkNode *ret ;

while(tmp)//遍历链表

{

ret = tmp;

tmp = tmp -> next;

free(ret);//释放结点空间

ret = NULL;

}

free(dl);

dl = NULL;

return 0;

}

(2)删除

int DeleteDouLinkList(struct DouLinkList* dl,char* name)

{

DouLinkNode *tmp = FindDouLinkList(dl,name);//查找待删结点

if(NULL == tmp -> prev)//头删

{

dl -> head = tmp -> next;

tmp -> next -> prev = NULL;

dl -> clen--;

free(tmp);

tmp = NULL;

return 0;

}

else if(NULL == tmp -> next)//尾删

{

tmp -> prev -> next = NULL;

dl -> clen--;

free(tmp);

tmp = NULL;

return 0;

}

else

{

tmp -> prev ->next = tmp -> next;

tmp -> next ->prev = tmp -> prev;

dl -> clen--;

free(tmp);

tmp = NULL;

return 0;

}

}

(3)逆序

int RevertDouLinkList(struct DouLinkList* dl)

{

DouLinkNode *p = NULL;//定义一个指向被逆转结点的指针,初始位空指针

DouLinkNode *tmp = dl -> head;//定义一个指向待逆转结点的指针,初始化位头指针

DouLinkNode *n = tmp ->next;//定义一个指向待逆转结点next的指针,辅助遍历链表

int len = GetsizeofDouLinkList(dl);

if(len < 2)//逆序链表长度必须大于1

{

return 1;

}

while(1)

{

tmp -> next = p;//将待逆序结点指向被逆序节点

tmp -> prev = n;

p = tmp;//p++

tmp = n;//tmp++

if(NULL == tmp)//判断指针是否为空

{

break;//指针为空时结束循环

}

n = n -> next;//n++

}

dl -> head = p;//将头指针指向已逆序后的链表首位

return 0;

}

注:

1.Makefile: vi Makefile

自动指定编译

(1)简单编译设置

(2)复杂编译设置

相关推荐
张张努力变强1 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
wWYy.1 小时前
数组快排 链表归并
数据结构·链表
李斯啦果1 小时前
【PTA】L1-019 谁先倒
数据结构·算法
Mr Xu_17 小时前
告别硬编码:前端项目中配置驱动的实战优化指南
前端·javascript·数据结构
czxyvX17 小时前
017-AVL树(C++实现)
开发语言·数据结构·c++
数智工坊17 小时前
【数据结构-队列】3.2 队列的顺序-链式实现-双端队列
数据结构
elseif12317 小时前
【C++】并查集&家谱树
开发语言·数据结构·c++·算法·图论
徐小夕@趣谈前端18 小时前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
Nebula_g18 小时前
线程进阶: 无人机自动防空平台开发教程(更新)
java·开发语言·数据结构·学习·算法·无人机
xuxie9919 小时前
day 23 树
数据结构