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

郑州建网站的好处seo培训价格

郑州建网站的好处,seo培训价格,网站 管理,wordpress选择windows还是(数据结构)带头双向循环链表 前言 前面链表部分,咱们着重讲解了不带头单向不循环链表,简称单链表。那么链表其实也分很多种类适用于各种各样的场景。通过单链表的学习,其实我们已经大致了解了链表的绝大多数的内容,所以接下来我通…

(数据结构)带头双向循环链表

前言

  • 前面链表部分,咱们着重讲解了不带头单向不循环链表,简称单链表。那么链表其实也分很多种类适用于各种各样的场景。通过单链表的学习,其实我们已经大致了解了链表的绝大多数的内容,所以接下来我通过再为大家讲解一个带头双向循环链表,那么剩下的链表的种类大家就可以各自组合,各自书写了。
  • 链表种类:
    在这里插入图片描述
  • 两种代表链表:
  • 在这里插入图片描述
    1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
    2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带 来很多优势,实现反而简单了,后面我们代码实现了就知道了。

整体的实现代码如下:(头文件)

 #include<stdio.h>#include<stdlib.h>#include<assert.h>//对int类型取别名是为了后续方便更改数据类型typedef int LTDateType;//链表节点的结构typedef struct ListNode{struct ListNode *prev;struct ListNode *next;LTDateType date;}LTNode;//动态申请一个节点LTNode *BuyLTNode(LTDateType x);//对链表进行初始化LTNode *LTInit();//打印链表void LTPrint(LTNode* phead);//尾部插入数据void LTpushBack(LTNode *phead,LTDateType x);//尾部删除数据void LTpopBack(LTNode* phead);//头部插入数据void LTpushFront(LTNode *phead,LTDateType x);//头部删除数据void LTpopFront(LTNode* phead);//计算链表中有效数据的个数int LTSize(LTNode* phead);//查找数据值为x的节点LTNode *LTFind(LTNode *phead,LTDateType x);//在pos节点前插入数据为x的节点void LTInsert(LTNode* pos, LTDateType x);//删除pos位置处的节点void LTErase(LTNode* pos);//销毁链表void LTDestroy(LTNode* phead);
  • 函数实现文件:
 #include "List.h"LTNode *BuyLTNode(LTDateType x){LTNode *node= (LTNode*)malloc(sizeof (LTNode));if(node==NULL){perror("malloc fail");exit(-1);}node->date=x;node->next=NULL;node->prev=NULL;return node;}LTNode *LTInit(){LTNode *phead= BuyLTNode(-1);phead->prev=phead;phead->next=phead;return phead;}void LTPrint(LTNode* phead){assert(phead);printf("phead<->");LTNode *cur=phead->next;while(cur!=phead){printf("%d<->",cur->date);cur=cur->next;}printf("phead\n");}void LTpushBack(LTNode *phead,LTDateType x){//判断phead是否为空指针assert(phead);//尾节点如下,无需再去遍历寻找尾节点LTNode *tail=phead->prev;//创建一个新节点LTNode *newnode=BuyLTNode(x);//改变指针指向,将尾节点与新节点相连newnode->prev=tail;tail->next=newnode;newnode->next=phead;phead->prev=newnode;}void LTpopBack(LTNode* phead){assert(phead);if (phead->next == phead)exit(-1);else{LTNode *tail=phead->prev;phead->prev=tail->prev;phead->prev->next=phead;free(tail);}}void LTpushFront(LTNode *phead,LTDateType x){assert(phead);/*  LTNode *newnode= BuyLTNode(x);newnode->next=phead->next;phead->next->prev=newnode;phead->next=newnode;newnode->prev=phead;*/LTNode *newnode= BuyLTNode(x);LTNode *first=phead->next;phead->next=newnode;newnode->prev=phead;newnode->next=first;first->prev=newnode;}void LTpopFront(LTNode* phead){assert(phead);if (phead->next == phead)exit(-1);else{/* LTNode *first=phead->next;phead->next=first->next;phead->next->prev=phead;free(first);*/LTNode *first=phead->next;LTNode *second=first->next;free(first);phead->next=second;second->prev=phead;}}int LTSize(LTNode* phead){assert(phead);int size=0;LTNode *cur=phead->next;while(cur!=phead){size++;cur=cur->next;}return size;}LTNode *LTFind(LTNode *phead,LTDateType x){assert(phead);LTNode *cur=phead->next;while(cur!=phead){if(cur->date==x)return cur;cur=cur->next;}return NULL;}void LTInsert(LTNode* pos, LTDateType x){assert(pos);LTNode *posPrev=pos->prev;LTNode *newnode= BuyLTNode(x);posPrev->next=newnode;newnode->prev=posPrev;newnode->next=pos;pos->prev=newnode;}void LTErase(LTNode* pos){assert(pos);/*    pos->prev->next=pos->next;pos->next->prev=pos->prev;free(pos);*/LTNode *posPrev=pos->prev;LTNode *posNext=pos->next;free(pos);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);}
  • 测试文件:(这里的测试文件,其实就是大家调用写好的函数,看功能是否正确,大家可以自行更改,这里只是一个示例)
 #include "List.h"void test1(){LTNode *plist=LTInit();LTpushBack(plist,1);LTpushBack(plist,2);LTpushBack(plist,3);LTpushBack(plist,4);LTPrint(plist);int c= LTSize(plist);printf("%d\n",c);LTNode *node= LTFind(plist,3);LTInsert(node,6);LTErase(node);LTPrint(plist);LTDestroy(plist);plist=NULL;}int main(){test1();return 0;}

函数逐个讲解:

  1. 第一个动态申请链表节点:
 LTNode *BuyLTNode(LTDateType x){LTNode *node= (LTNode*)malloc(sizeof (LTNode));if(node==NULL){perror("malloc fail");exit(-1);}node->date=x;node->next=NULL;node->prev=NULL;return node;}
  • 这个函数没什么好说的,就是用malloc和sizeof来申请节点,如果申请成功就赋值,失败则exit。
  1. 初始化函数:
LTNode *LTInit()
{LTNode *phead= BuyLTNode(-1);phead->prev=phead;phead->next=phead;return phead;
}
  • 在这里插入图片描述
  1. 打印函数:

    void LTPrint(LTNode* phead)
    {assert(phead);printf("phead<->");LTNode *cur=phead->next;while(cur!=phead){printf("%d<->",cur->date);cur=cur->next;}printf("phead\n");
    }
    

在这里插入图片描述
4. 尾部插入函数:

void LTpushBack(LTNode *phead,LTDateType x)
{//判断phead是否为空指针assert(phead);//尾节点如下,无需再去遍历寻找尾节点LTNode *tail=phead->prev;//创建一个新节点LTNode *newnode=BuyLTNode(x);//改变指针指向,将尾节点与新节点相连newnode->prev=tail;tail->next=newnode;newnode->next=phead;phead->prev=newnode;}

在这里插入图片描述
5. 尾部删除函数

void LTpopBack(LTNode* phead)
{assert(phead);if (phead->next == phead)exit(-1);else{LTNode *tail=phead->prev;phead->prev=tail->prev;phead->prev->next=phead;free(tail);}
}

在这里插入图片描述
6. 头部插入函数

void LTpushFront(LTNode *phead,LTDateType x)
{assert(phead);
/*  LTNode *newnode= BuyLTNode(x);newnode->next=phead->next;phead->next->prev=newnode;phead->next=newnode;newnode->prev=phead;
*/LTNode *newnode= BuyLTNode(x);LTNode *first=phead->next;phead->next=newnode;newnode->prev=phead;newnode->next=first;first->prev=newnode;}

在这里插入图片描述
7. 头部删除函数

void LTpopFront(LTNode* phead)
{assert(phead);if (phead->next == phead)exit(-1);else{/* LTNode *first=phead->next;phead->next=first->next;phead->next->prev=phead;free(first);*/LTNode *first=phead->next;LTNode *second=first->next;free(first);phead->next=second;second->prev=phead;}}

在这里插入图片描述
8. 计算有效节点个数

int LTSize(LTNode* phead)
{assert(phead);int size=0;LTNode *cur=phead->next;while(cur!=phead){size++;cur=cur->next;}return size;
}

在这里插入图片描述

  • 补充一点就是,我这里是因为哨兵位的结构和链表节点的结构是一样的,是共用链表节点的结构的。也就是说,哨兵位里面的date的类型是和链表节点里存的数据类型是一样的,都是LTDataType。所以这里的如果要用哨兵位记录链表长度就只能是int类型,如果LTDataType变成了char类型这些,那么哨兵位里的data+1结果就会不如人意了,字符+1和int整型+1那肯定是不一样的结果嘛。
  • 但是如果你就要哨兵位记录链表长度,那就单独再创建一个哨兵位的结构,和链表节点的结构脱离,这个可以参考我讲队列的那篇文章。
  1. 查找数据的值为x的节点
LTNode *LTFind(LTNode *phead,LTDateType x)
{assert(phead);LTNode *cur=phead->next;while(cur!=phead){if(cur->date==x)return cur;cur=cur->next;}return NULL;}
  • 这里这个函数功能和上一个函数,也就是计算有效个数函数和打印函数实现逻辑类似,就不多说了。
  1. 在pos位置前插入值为x的节点
void LTInsert(LTNode* pos, LTDateType x)
{assert(pos);LTNode *posPrev=pos->prev;LTNode *newnode= BuyLTNode(x);posPrev->next=newnode;newnode->prev=posPrev;newnode->next=pos;pos->prev=newnode;}

在这里插入图片描述

  • 这个函数也可以复用在尾插和头插函数里
  1. 删除pos位置的节点

void LTErase(LTNode* pos)
{assert(pos);/*    pos->prev->next=pos->next;pos->next->prev=pos->prev;free(pos);*/LTNode *posPrev=pos->prev;LTNode *posNext=pos->next;free(pos);posPrev->next=posNext;posNext->prev=posPrev;}

在这里插入图片描述

  • 这个函数也可以复用在尾删和头删里
  1. 链表销毁函数
void LTDestroy(LTNode* phead)
{assert(phead);LTNode *cur=phead->next;while(cur!=phead){LTNode *next=cur->next;free(cur);cur=next;}}

在这里插入图片描述

  • 到此,链表的内容就全部讲完了。
http://www.dtcms.com/wzjs/28742.html

相关文章:

  • 北京网站优化对策中国优化网
  • 大学生网站建设结题报告seo网站关键词排名快速
  • 重庆专业网站建设公司哪家好百度收录怎么查询
  • 国家疫情防控最新政策第十版深圳百度推广seo公司
  • 网站策划要遵循的原则中国婚恋网站排名
  • 黄岩城乡住房和建设局网站游戏优化是什么意思
  • 苏州企业管理咨询服务网站及搜索引擎优化建议
  • 德阳网站建设.comseo分析工具有哪些
  • 网站设计就业岗位分析网站制作费用
  • 网站建设惠州国内seo公司
  • 资料查询网站建设合肥网站seo推广
  • 网站首页 选择入口 设计北京seo顾问推推蛙
  • 电商网站网址大全学历提升哪个教育机构好一些
  • wordpress对php版本seo人才网
  • 专业seo网站天津seo排名扣费
  • 网站验证码插件活动营销方案
  • .xyz做网站怎么样网站分为哪几种类型
  • 南宁网站建设推广app定制开发
  • 网站搭建 商城 seo百度刷排名百度快速排名
  • 表格如何给网站做链接地址网络营销课程培训机构
  • 拍卖网站建设需求整合营销推广
  • 南宁网站建设怎么样广告投放优化师
  • 南开网站建设公司交换友情链接平台
  • 海南省住房与城乡建设厅网站链接
  • 所以免费爱做网站seo外包公司兴田德润
  • seo网站制作百度公司有哪些部门
  • Wordpress 跨域登录青岛seo博客
  • gta5买办公室 网站正在建设网站alexa排名
  • 网站怎么做弹窗免费数据统计网站
  • 沈阳专业网站制作自媒体发稿