当前位置: 首页 > news >正文

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

一、双向链表

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

5.  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;}

相关文章:

  • js关于number类型的计算问题
  • RabbitMQ工作流程及使用方法
  • c/c++消息队列库RabbitMQ的使用
  • 动态库和静态库的区别
  • 以项目的方式学QT开发(二)
  • 哲学物理:太极图和莫比乌斯环有什么关系?
  • OkHttp用法-Java调用http服务
  • 【Linux系列】Linux 系统下 SSD 磁盘识别
  • 【油藏地球物理正演软件ColchisFM】基于数据驱动的油藏参数叠前地震反演研究进展
  • 操作系统学习笔记第3章 内存管理(灰灰题库)
  • javaSE.QueueDeque
  • python打卡打印26
  • Git 常用命令详解
  • 进程替换讲解
  • 【day01】 Chroma 核心操作流程
  • IT系统的基础设施:流量治理、服务治理、资源治理,还有数据治理。
  • 部署安装jenkins.war(2.508)
  • 练习小项目2:今日幸运颜色生成器
  • 【ALINX 实战笔记】FPGA 大神 Adam Taylor 使用 ChipScope 调试 AMD Versal 设计
  • 在Angular中使用Leaflet构建地图应用
  • 外企聊营商|武田制药:知识产权保护助创新药研发
  • 马上评|清理“滥竽充数者”,为医者正名
  • 新任国防部新闻发言人蒋斌正式亮相
  • 六连板成飞集成:航空零部件业务收入占比为1.74%,市场环境没有重大调整
  • 重庆市委原常委、政法委原书记陆克华被决定逮捕
  • 王毅谈中拉命运共同体建设“五大工程”及落实举措