自学嵌入式 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)复杂编译设置

相关推荐
CSharp精选营3 天前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
刘马想放假6 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠7 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
Darling噜啦啦14 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠15 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾15 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
Qres82115 天前
算法复键——树状数组
数据结构·算法
牛油果子哥q15 天前
并查集(DSU)超精讲,路径压缩、按秩合并、万能模板、连通性判定、最小生成树与刷题实战全解
数据结构·c++·最小生成树·并查集
凌波粒15 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
疯狂成瘾者15 天前
Java 集合 LinkedList 详解:链表结构、常用方法和队列使用
java·开发语言·链表