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

官方网站下载免费app域名注册网站查询

官方网站下载免费app,域名注册网站查询,网站设计怎么设计学生作业,建筑人才网官网档案查询目录 前言 1. 双向链表 带头双向循环链表的结构 2. 链表的实现 2.1 初始化 2.2 尾插 2.3 尾删 2.4 头插 2.5 头删 2.6 在pos位置之前插入 2.7 删除pos位置 3.双向链表完整源码 List.h List.c 前言 在上一期中我们介绍了单链表,也做了一些练习题&…

目录

前言

1. 双向链表 

带头双向循环链表的结构

2. 链表的实现

2.1 初始化

2.2 尾插

2.3 尾删

2.4 头插

2.5 头删

2.6 在pos位置之前插入

2.7 删除pos位置

3.双向链表完整源码

List.h

List.c


前言

在上一期中我们介绍了单链表,也做了一些练习题,在一些题中使用单链表会十分繁琐。因为单链表只能正着走,不能倒着走,例如:回文、逆置。本期我们将学习带头双向循环链表。

1. 双向链表 

带头双向循环链表的结构

 特点:带头双向循环链表结构最复杂,一般用在单独存储数据。结构虽然结构复杂,但是使用代码实现以后会发现结构会带来多优势,实现反而简单了。

2. 链表的实现

2.1 初始化

LTNode* LTInit()
{LTNode* phead = CreateLTNode(-1);phead->next = phead;phead->prev = phead;return phead;
}

2.2 尾插

带哨兵位的链表尾插时不用判断是否有节点,两种情况的插入相同,而且还不用传递二级指针。

void LTPushBack(LTNode* phead, LTDateType x)
{assert(phead);LTNode* newnode = CreateLTNode(x);phead->prev->next = newnode;newnode->prev = phead->prev;newnode->next = phead;phead->prev = newnode;
}

2.3 尾删

在尾删时我们通过 assert(phead->next != phead);  判断链表是否有节点。同时这个代码就有普遍性,不用单独考虑剩一个节点的情况。

void LTPopBack(LTNode* phead)
{assert(phead);LTNode* tail = phead->prev;LTNode* tailprev = tail->prev;free(tail);phead->prev = tailprev;tailprev->next = phead;
}

2.4 头插

头删重要的是赋值的顺序,顺序错误会找不到后面的节点,导致内存泄漏。带哨兵位的链表不需要传递二级指针,因为改变的是结构体的变量。

void LTPushFront(LTNode* phead, LTDateType x)
{assert(phead);LTNode* newnode = CreateLTNode(x);newnode->next = phead->next;phead->next->prev = newnode;phead->next = newnode;newnode->prev = phead;
}

2.5 头删

我们可以多定义几个指针来保存后面节点的地址,这样就不会造成节点的丢失,不用考虑赋值的顺序,会更加方便。 

void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* tail = phead->next;LTNode* next = tail->next;phead->next = next;next->prev = phead;free(tail);tail = NULL;
}

2.6 在pos位置之前插入

void LTInsert(LTNode* pos, LTDateType x)
{assert(pos);LTNode* posprev = pos->prev;LTNode* newnode = CreateLTNode(x);posprev->next = newnode;newnode->prev = posprev;newnode->next = pos;pos->prev = newnode;
}

2.7 删除pos位置

void LTErase(LTNode* pos)
{assert(pos);LTNode* posprev = pos->prev;LTNode* posnext = pos->next;posprev->next = posnext;posnext->prev = posprev;
}

3.双向链表完整源码

List.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int LTDateType;typedef struct ListNode
{LTDateType val;struct ListNode* next;struct ListNode* prev;
}LTNode;LTNode* LTInit();void LTPrint(LTNode* phead);void LTPushBack(LTNode* phead, LTDateType x);void LTPushFront(LTNode* phead, LTDateType x);void LTPopBack(LTNode* phead);void LTPopFront(LTNode* phead);LTNode* LTFind(LTNode* phead, LTDateType x);void LTInsert(LTNode* pos, LTDateType x);void LTErase(LTNode* pos);void LTDestroy(LTNode* phead);

List.c

#include"List.h"LTNode* CreateLTNode(LTDateType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->val = x;newnode->next = NULL;newnode->prev = NULL;
}LTNode* LTInit()
{LTNode* phead = CreateLTNode(-1);phead->next = phead;phead->prev = phead;return phead;
}void LTPrint(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;printf("<=>哨兵位<=>");while (cur != phead){printf("%d<=>", cur->val);cur = cur->next;}printf("\n");
}void LTPushBack(LTNode* phead, LTDateType x)
{assert(phead);LTNode* newnode = CreateLTNode(x);phead->prev->next = newnode;newnode->prev = phead->prev;newnode->next = phead;phead->prev = newnode;
}void LTPushFront(LTNode* phead, LTDateType x)
{assert(phead);LTNode* newnode = CreateLTNode(x);newnode->next = phead->next;phead->next->prev = newnode;phead->next = newnode;newnode->prev = phead;
}void LTPopBack(LTNode* phead)
{assert(phead);LTNode* tail = phead->prev;LTNode* tailprev = tail->prev;free(tail);phead->prev = tailprev;tailprev->next = phead;
}void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* tail = phead->next;LTNode* next = tail->next;phead->next = next;next->prev = phead;free(tail);tail = NULL;
}LTNode* LTFind(LTNode* phead, LTDateType x)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){if (cur->val == x){return cur;}cur = cur->next;}return NULL;
}void LTInsert(LTNode* pos, LTDateType x)
{assert(pos);LTNode* posprev = pos->prev;LTNode* newnode = CreateLTNode(x);posprev->next = newnode;newnode->prev = posprev;newnode->next = pos;pos->prev = newnode;
}void LTErase(LTNode* pos)
{assert(pos);LTNode* posprev = pos->prev;LTNode* posnext = pos->next;posprev->next = posnext;posnext->prev = posprev;
}void LTDestroy(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){LTNode* next = cur->next;free(cur);cur = next;}free(phead);phead = NULL;
}

通过上面链表的实现,我们已经感受到了带头双向循环链表的方便和简单,它不需要去考虑链表是否有元素,还可以找到前一个元素,在我们使用中提供很大的便利。

本次的内容到这里就结束啦。希望大家阅读完可以有所收获,同时也感谢各位读者三连支持。文章有问题可以在评论区留言,博主一定认真认真修改,以后写出更好的文章。 

http://www.mmbaike.com/news/111061.html

相关文章:

  • 怎么做品牌推广网站免费建网页
  • 精品课程网站建设seo优化网站推广
  • 苏州苏州设计公司公司seo排名优化
  • 江河建设集团有限公司网站上海网络seo
  • 公安网站备案系统百度网盘官网入口
  • 图片点开是网站怎么做优化设计七年级上册语文答案
  • 中国互联网公司排名100强潍坊seo按天收费
  • 温州专业微网站制作电话汕头seo优化公司
  • 做网站的公司属于什么行业腾讯中国联通
  • 网站英文域名是什么百度收录链接
  • 建设网站对公司起什么作用是什么北京网络营销
  • 网站不提交表单在线友情链接
  • 青岛网站建站群发软件
  • 临西做网站哪里便宜创建网址链接
  • 分页网站在线优化网站
  • 手机怎么自己做网站网站模板源码
  • 网站12栅格系统怎么做网站客服系统
  • 三明网站优化互联网销售怎么做
  • 党建网站建设成效网络推广外包公司
  • 怎样做寻亲网站志愿者长尾关键词挖掘工具爱网站
  • 搭建论坛网站的流程南昌seo实用技巧
  • 自助建站基础工作主要包括()网络加速器
  • 正鹏建设工程有限公司网站新型实体企业100强
  • 网站改版 被百度k关键词抓取工具都有哪些
  • 网站开发师招聘英文外链代发
  • 163网站源码免费推广网站注册入口
  • 公司网站模板免费源码下载最近发生的热点新闻
  • 小象编程官网登录入口成都官网seo厂家
  • 郑州建站模板搭建seo是对网站进行什么优化
  • 网站组成元素广州seo优化推广