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

网站建设论文伯乐在线企业网站建设公司怎么收费

网站建设论文伯乐在线,企业网站建设公司怎么收费,上海牛巨微seo,重庆网站域名备案地址目录 一.带头双向循环链表的定义 二.带头双向循环链表的功能实现 2.1.带头双向循环链表的定义 2.2.带头双向循环链表的结点创建 2.3.带头双向循环链表的初始化 2.4.带头双向循环链表的打印 2.5.带头双向循环链表的判空 2.6.带头双向循环链表的尾插 2.7.带头双向循环链…目录 一.带头双向循环链表的定义 二.带头双向循环链表的功能实现 2.1.带头双向循环链表的定义 2.2.带头双向循环链表的结点创建 2.3.带头双向循环链表的初始化 2.4.带头双向循环链表的打印 2.5.带头双向循环链表的判空 2.6.带头双向循环链表的尾插 2.7.带头双向循环链表的头插 2.8.带头双向循环链表的尾删 2.9.带头双向循环链表的头删 2.10.带头双向循环链表的在pos位置之前插入 2.11.带头双向循环链表的删除pos位置的结点 2.12.带头双向循环链表的求链表长度 2.13.带头双向循环链表的销毁 2.14.完整程序 List.h List.c test.c 三. 顺序表和链表的比较 逻辑结构 存储结构 基本操作 创建 销毁 增加与删除 查找 一.带头双向循环链表的定义 循环单链表虽然能够实现从任一结点出发沿着链能找到其前驱结点但时间耗费是O(n)。如果希望从表中快速确定某一个结点的前驱另一个解决方法就是在单链表的每个结点里再增加一个指向其前驱的指针域prior。这样形成的链表中就有两条方向不同的链称之为双(向)链表。 与单链表类似双链表也可增加头结点使双链表的某些运算变得方便。同时双向链表也可以有循环表称为双向循环链表。 由于在双向链表中既有前向链又有后向链寻找任一结点的直接前驱结点与直接后继结点都变得非常方便了。 二.带头双向循环链表的功能实现 2.1.带头双向循环链表的定义 //定义 typedef int LTDataType;typedef struct ListNode {struct ListNode* next;struct ListNode* pre;LTDataType data; }LTNode; 与单链表的定义不同带头双向循环链表要定义两个指针前驱指针pre和后继指针next。前驱指针pre用于指向当前结点的上一个结点后继指针next用于指向当前结点的下一个结点。 2.2.带头双向循环链表的结点创建 LTNode* BuyListNode(LTDataType x) {//动态开辟一个结点nodeLTNode* node (LTNode*)malloc(sizeof(LTNode));//判空if (node NULL){perror(malloc fail!);exit(-1);}//前驱与后继结点均置为空node-data x;node-next NULL;node-pre NULL;return node; } 结点的创建主要是通过调用malloc函数来实现初始化时要将前驱指针和后继指针都置为NULL。 2.3.带头双向循环链表的初始化 版本一 void ListInit(LTNode** phead) {//这里需要传入二级指针即传地址才能实现对链表的修改//判空assert(phead);//创建头结点*phead BuyListNode(-1);//将头结点的前驱指针和后继指针均指向自身(*phead)-next *phead;(*phead)-pre *phead; } 版本二 LTNode* ListInit() {//创建头结点LTNode* phead BuyListNode(-1);//将头结点的前驱指针和后继指针均指向自身phead-next phead;phead-pre phead;//返回头结点return phead; } 链表的初始化采用了两种方式传二级指针和设置返回值。 总结 如果要改变头指针就要传二级指针。不需要改变头指针的话则传入一级指针。 在使用带头结点的单链表时 初始化链表头指针需要传二级指针销毁链表需要传二级指针插入、删除、遍历、清空结点用一级指针即可。 不带头结点的单链表除了初始化和销毁插入、删除和清空结点也需要二级指针。 调试分析 2.4.带头双向循环链表的打印 void ListPrint(LTNode* phead) {//判空assert(phead);//cur指向链表的第一个结点LTNode* cur phead-next;//cur依次向后遍历直到cur重新回到头结点while (cur ! phead){printf(%d , cur-data);cur cur-next;}printf(\n); } 设置一个临时变量cur指向当前链表的第一个结点(非头结点)然后依次向后遍历该链表直到cur重新回到头结点phead的位置。 2.5.带头双向循环链表的判空 bool ListEmpty(LTNode* phead) {//判空assert(phead);//如果phead-next等于phead则链表为空返回true//如果phead-next不等于phead则链表不为空返回falsereturn phead-next phead; } 如果phead-next等于phead则链表为空返回true如果phead-next不等于phead则链表不为空返回false。 2.6.带头双向循环链表的尾插 void ListPushBack(LTNode* phead, LTDataType x) {//判空assert(phead);//创建新结点LTNode* newnode BuyListNode(x);//查找尾结点LTNode* tail phead-pre;//尾插//原尾和新尾相互链接tail-next newnode;newnode-pre tail;//头结点和新尾相互链接newnode-next phead;phead-pre newnode; } 相较于单链表的尾插带头双向循环链表的尾插不需要从头结点开始依次向后遍历因为头结点的前驱结点便指向尾结点tail。在找到尾结点tail之后便可将新结点newnode插入到尾结点tail的后面。此时newnode变为新的尾结点。 调试分析 运行结果 2.7.带头双向循环链表的头插 void ListPushFront(LTNode* phead, LTDataType x) {//判空assert(phead);//创建新结点LTNode* newnode BuyListNode(x);//头插//phead newnode next三者不分先后顺序//法一LTNode* next phead-next;phead-next newnode;newnode-pre phead;newnode-next next;next-pre newnode;//phead newnode phead-next先处理后两个再处理前两个//法二//phead-next-pre newnode;//newnode-next phead-next;//phead-next newnode;//newnode-pre phead; } 在进行头插时要注意结点之间插入的先后顺序这里主要介绍两种方式。方式一创建一个临时变量next然后将头结点的下一个结点保存在next当中。首先调用BuyListNode(x)创建一个新结点newnode然后将pheadnewnode和next三个结点进行链接。三个结点不分先后顺序直接进行链接即可。该方式最为简单也最不容易出错方式二不创建临时变量next。首先调用BuyListNode(x)创建一个新结点newnode然后将pheadnewnode和phead-next三个结点进行链接。链接是关键要先将后两个结点进行链接然后再将前两个结点进行链接。三个结点一定要注意先后顺序不可随意链接。 调试分析 运行结果 2.8.带头双向循环链表的尾删 void ListPopBack(LTNode* phead) {//判空assert(phead);//判断链表是否为空assert(phead-next ! phead);//assert(!ListEmpty(phead));//找尾结点LTNode* tail phead-pre;//找尾结点的前一结点LTNode* tailPre tail-pre;//释放尾结点free(tail);tailPre-next phead;phead-pre tailPre; } 在进行尾删之前首先要判断链表是否为空可以通过phead-next ! phead进行判断也可以调用ListEmpty(phead)函数进行判断然后找到链表的尾结点tail以及链表尾结点的前一个结点tailPre接着调用free函数释放尾结点tail并将tailPre作为新的尾结点最后再将新的尾结点与头结点phead进行相连即可。 调试分析 运行结果 2.9.带头双向循环链表的头删 void ListPopFront(LTNode* phead) {//判空assert(phead);//判断链表是否为空assert(phead-next ! phead);//assert(!ListEmpty(phead));//tail记录第一个结点之后的下一个结点LTNode* tail phead-next-next;//释放第一个结点free(phead-next);//将头结点和tail相链接phead-next tail;tail-pre phead; } 在进行头删之前首先要判断链表是否为空可以通过phead-next ! phead进行判断也可以调用ListEmpty(phead)函数进行判断然后找到链表的第二个有效结点tail接着调用free函数释放掉第一个有效结点并将tail作为新的第一个有效结点最后再将新的第一个结点tail与头结点phead进行相连即可。 调试分析 运行结果 2.10.带头双向循环链表的在pos位置之前插入 void ListInsert(LTNode* pos, LTDataType x) {//判空assert(pos);//查找pos的前一个结点LTNode* pre pos-pre;//创建新结点LTNode* newnode BuyListNode(x);//pre newnode pospre-next newnode;newnode-pre pre;newnode-next pos;pos-pre newnode; } 给定一个结点pos如果是带头双向循环链表那么pos之前的结点和pos之后的结点都是可知的。要在pos位置之前插入首先要找到pos的前一结点pre然后调用BuyListNode(x)创建一个新结点newnode接着将prenewnode和pos三个结点进行链接即可。此时pos位置的结点将由pos变为newnode。 调试分析 运行结果 2.11.带头双向循环链表的删除pos位置的结点 void ListErase(LTNode* pos) {//判空assert(pos);//查找pos的前一个结点LTNode* pre pos-pre;//查找pos的后一个结点LTNode* next pos-next;//将前一个结点pre与后一个结点next相链接pre-next next;next-pre pre;//释放pos结点free(pos); } 在删除pos位置的结点之前首先要找到pos位置的前一个结点pre然后找到pos位置的后一个结点next接着将结点pre与next相链接最后再调用free函数释放掉pos结点即可。 调试分析 运行结果 2.12.带头双向循环链表的求链表长度 int ListSize(LTNode* phead) {//判空assert(phead);//cur指向当前链表的第一个结点LTNode* cur phead-next;//用于记录遍历过的结点数int size 0;//从第一个结点开始依次向后遍历直到遍历到头结点while (cur ! phead){size;cur cur-next;}return size; } 调试分析 运行结果 2.13.带头双向循环链表的销毁 void ListDestory(LTNode* phead) {//判空assert(phead);//cur指向当前第一个结点LTNode* cur phead-next;while (cur ! phead){//保存cur的下一个结点LTNode* next cur-next;//删除curListErase(cur);//更新curcur next;}//释放头结点free(phead); } 调试分析 运行结果 2.14.完整程序 List.h #pragma once#includestdio.h #includestdlib.h #includeassert.h #includestdbool.h//带头双向循环链表//定义 typedef int LTDataType;typedef struct ListNode {struct ListNode* next;struct ListNode* pre;LTDataType data; }LTNode;//创建结点 LTNode* BuyListNode(LTDataType x);//初始化版本一 //void ListInit(LTNode** phead);//初始化版本二 LTNode* ListInit();//打印 void ListPrint(LTNode* phead);//判空 bool ListEmpty(LTNode* phead);//尾插 //不用二级指针的原因尾插时不会改变phead因为它带哨兵位尾插时不会对哨兵位进行修改 void ListPushBack(LTNode* phead, LTDataType x);//头插 void ListPushFront(LTNode* phead, LTDataType x);//尾删 void ListPopBack(LTNode* phead);//头删 void ListPopFront(LTNode* phead);//在pos位置之前插入 void ListInsert(LTNode* pos, LTDataType x);//删除pos位置的结点 void ListErase(LTNode* pos);//链表长度 int ListSize(LTNode* phead);//销毁 void ListDestory(LTNode* phead); List.c #define _CRT_SECURE_NO_WARNINGS 1#includeList.h//创建结点 LTNode* BuyListNode(LTDataType x) {//动态开辟一个结点nodeLTNode* node (LTNode*)malloc(sizeof(LTNode));//判空if (node NULL){perror(malloc fail!);exit(-1);}//前驱与后继结点均置为空node-data x;node-next NULL;node-pre NULL;return node; }//初始化 /* void ListInit(LTNode** phead) {//这里需要传入二级指针即传地址才能实现对链表的修改//判空assert(phead);//创建头结点*phead BuyListNode(-1);//将头结点的前驱指针和后继指针均指向自身(*phead)-next *phead;(*phead)-pre *phead; } *///初始化 LTNode* ListInit() {//创建头结点LTNode* phead BuyListNode(-1);//将头结点的前驱指针和后继指针均指向自身phead-next phead;phead-pre phead;//返回头结点return phead; }//打印 void ListPrint(LTNode* phead) {//判空assert(phead);//cur指向链表的第一个结点LTNode* cur phead-next;//cur依次向后遍历直到cur重新回到头结点while (cur ! phead){printf(%d , cur-data);cur cur-next;}printf(\n); }//判空 bool ListEmpty(LTNode* phead) {//判空assert(phead);//如果phead-next等于phead则链表为空返回true//如果phead-next不等于phead则链表不为空返回falsereturn phead-next phead; }//尾插 void ListPushBack(LTNode* phead, LTDataType x) {//判空assert(phead);/*//创建新结点LTNode* newnode BuyListNode(x);//查找尾结点LTNode* tail phead-pre;//尾插//原尾和新尾相互链接tail-next newnode;newnode-pre tail;//头结点和新尾相互链接newnode-next phead;phead-pre newnode;*///尾插ListInsert(phead, x);//是phead而不是phead-pre }//头插 void ListPushFront(LTNode* phead, LTDataType x) {//判空assert(phead);/*//创建新结点LTNode* newnode BuyListNode(x);//头插//phead newnode next三者不分先后顺序//法一LTNode* next phead-next;phead-next newnode;newnode-pre phead;newnode-next next;next-pre newnode;//phead newnode phead-next先处理后两个再处理前两个//法二//phead-next-pre newnode;//newnode-next phead-next;//phead-next newnode;//newnode-pre phead;*///头插ListInsert(phead-next, x); }//尾删 void ListPopBack(LTNode* phead) {//判空assert(phead);//判断链表是否为空assert(phead-next ! phead);//assert(!ListEmpty(phead));/*//找尾结点LTNode* tail phead-pre;//找尾结点的前一结点LTNode* tailPre tail-pre;//释放尾结点free(tail);tailPre-next phead;phead-pre tailPre;*///尾删ListErase(phead-pre); }//头删 void ListPopFront(LTNode* phead) {//判空assert(phead);//判断链表是否为空assert(phead-next ! phead);//assert(!ListEmpty(phead));/*//tail记录第一个结点之后的下一个结点LTNode* tail phead-next-next;//释放第一个结点free(phead-next);//将头结点和tail相链接phead-next tail;tail-pre phead;*///头删ListErase(phead-next); }//在pos位置之前插入x void ListInsert(LTNode* pos, LTDataType x) {//判空assert(pos);//查找pos的前一个结点LTNode* pre pos-pre;//创建新结点LTNode* newnode BuyListNode(x);//pre newnode pospre-next newnode;newnode-pre pre;newnode-next pos;pos-pre newnode; }//删除pos位置的结点 void ListErase(LTNode* pos) {//判空assert(pos);//查找pos的前一个结点LTNode* pre pos-pre;//查找pos的后一个结点LTNode* next pos-next;//将前一个结点pre与后一个结点next相链接pre-next next;next-pre pre;//释放pos结点free(pos); }//链表长度 int ListSize(LTNode* phead) {//判空assert(phead);//cur指向当前链表的第一个结点LTNode* cur phead-next;//用于记录遍历过的结点数int size 0;//从第一个结点开始依次向后遍历直到遍历到头结点while (cur ! phead){size;cur cur-next;}return size; }//销毁 void ListDestory(LTNode* phead) {//判空assert(phead);//cur指向当前第一个结点LTNode* cur phead-next;while (cur ! phead){//保存cur的下一个结点LTNode* next cur-next;//法一删除cur//ListErase(cur);//法二删除curfree(cur);//更新curcur next;}//释放头结点free(phead); } test.c #define _CRT_SECURE_NO_WARNINGS 1#includeList.hvoid test() {LTNode* plist NULL;//初始化plist ListInit();//头插ListPushFront(plist, 1);ListPushFront(plist, 2);ListPushFront(plist, 3);ListPushFront(plist, 4);ListPushFront(plist, 5);ListPrint(plist);ListDestory(plist);ListPrint(plist); }int main() {test();return 0; } 三. 顺序表和链表的比较 下面分别从逻辑结构存储结构基本操作的角度对顺序表和链表进行比较。 逻辑结构 都属于线性表都是线性结构。 存储结构 基本操作 对于任何一个数据结构基本操作基本都能归纳为创销增删改查。其中改建立在查的基础上。 创建 销毁 增加与删除 查找 用链表还是顺序表 顺序表          链表弹性可扩容             ×           √     增删             ×           √        改             √           × 表长难以预估经常需要增加/删除元素--链表 表长可预估查询搜索操作较多--顺序表
http://www.pierceye.com/news/110985/

相关文章:

  • 企业网站的建设与流程数据分析师要学什么课程
  • 重庆营销型网站随做的好谷歌广告投放教程
  • 个人公众号做网站广州市车管所网站建设
  • 上海网站建设公司排名王也诸葛青cp
  • 常用的设计网站有哪些wordpress如何汉化主题
  • 深圳全网营销型网站免费做调查的网站有哪些
  • 设计素材网站知乎济南seo网站推广
  • 网站建设类岗位杭州国家电网 两学一做 网站
  • html静态网站开发自我介绍网站手机客户端开发教程
  • 营销型网站是什么样的桂林北站有核酸检测点吗
  • 网站未备案被阻断怎么做it培训机构哪个好一点
  • 重庆建设注册执业中心网站网络营销百度百科
  • app网站怎么下载个人备案做视频网站
  • 西宁建一个网站公司广东网站备案
  • 网站数据比较北京网站优化推广公司
  • 想做网站的客户在哪找美间在线设计平台
  • 网站设计规划的目的和要求营销外贸网站建设案例
  • 网站营销力一级a做爰片2017免费网站
  • 昌图网站网页界面设计的要求
  • 做一个网站赚钱什么 门户网站
  • 中国建设银行购物网站帝国织梦wordpress
  • 瑞安网站网站建设松原公司做网站的流程
  • 做网站按页面收费视频解析网站如何做搜索
  • 太原网站的公司赣州安全教育平台
  • 淮北建投网站网站推广与维护有什么不同
  • 深圳网站备案注销平果县免费网站哪家好
  • 如何区分网站开发语言做网站多少钱一般
  • 定制专业app开发seo数据统计分析工具有哪些
  • 某服装公司网站建设论文网站建设seo虾哥网络
  • 网站建设销售员工作内容网站访问量过大