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

慈溪市建设局网站购物网站建设需求模板

慈溪市建设局网站,购物网站建设需求模板,腾讯云服务器如何使用,学校信息化网站建设文章目录 头节点(哨兵位)双向循环结构头插尾插头删尾删在指定位置之前插入数据删除指定位置之前的数据销毁链表 全部代码结语 单链表地址 头节点(哨兵位) 什么是头节点呢?头节点也叫哨兵节点,他在链表中进行不了任何操作,只是用来放哨用的,在单链表中我们当我们尾插的时候我们… 文章目录 头节点(哨兵位)双向循环结构头插尾插头删尾删在指定位置之前插入数据删除指定位置之前的数据销毁链表 全部代码结语 单链表地址 头节点(哨兵位) 什么是头节点呢?头节点也叫哨兵节点,他在链表中进行不了任何操作,只是用来放哨用的,在单链表中我们当我们尾插的时候我们呢需要判断此时的节点是否是空,如果不是空我们才可以尾插,是空的话我们直接赋值,而有了头节点我们就不需要判断是否为空了,直接在头节点后插入即可。这就是头节点的好处,尾插,尾删等也有好处(下文再说) 双向循环结构 在单链表中我们只有一个指针指向下一个节点,而双向链表则需要两个指针,一个指向前一个节点,一个指向后一个节点,由于我们需要循环起来,所以最后一个节点我们要指向头节点(这里是指第一个节点) 为了避免搞混我下文把第一个节点称为头节点,哨兵节点就为哨兵节点 哨兵节点如下: 注意这里我们是要创建一个哨兵节点,所以我们需要返回一个节点,而我们接下来的操作都是在哨兵节点的基础上进行的,所以每一次进行基本增删操作的时候可以传一级指针,因为我们接受的哨兵节点肯定是一个指针类型的。 结构定义如下: 代码实现: //创建哨兵节点 List* ListHeadCreat() {List* newhead (List*)malloc(sizeof(List));if (newhead NULL){printf(malloc fail!\n);exit(-1);}newhead-val -1;newhead-next newhead-prev newhead;return newhead; }头插 首先我们要创建一个新的节点,先让这个新的节点指向自己 头插这里分两种情况: 1. 只有一个哨兵节点 (1) newNode (新节点)的next指向phead,再让newNode的prev指向phead。 (2) phead-next指向newNode,再让phead-prev指向newNode 2. 不止一个节点 (1) newNode的next指向phead-prev(此时由于链表的最后一个元素就是哨兵节点的上一个节点),再让newNode-prev指phead (2) phead-prev指向newNode,phead-prev-next(最后一个节点的下一个节点)指向newNode 代码实现: //头插 void ListPushFront(List* phead, LDataType x) {assert(phead);List* newNode BuyNode(x); newNode-prev phead;newNode-next phead-next;phead-next newNode;//如果只有一个节点,要把此时的哨兵节点的上一个节点指向新插入的节点if (phead-prev phead)phead-prev newNode; }尾插 尾插无论是只有哨兵节点还是多个节点,代码操作都是一样的。 (1) newNode-next指向phead newNode-prev指向最后一个节点 (2) phead-prev-next(最后一个节点)指向newNode phead-prev(哨兵节点指向尾)指向newNode 代码实现: //尾插 void ListPushBack(List* phead, LDataType x) {assert(phead);List* newNode BuyNode(x);newNode-next phead;newNode-prev phead-prev;phead-prev-next newNode;phead-prev newNode; }头删 头删我们得先保证链表中还有元素,所以我们需要判断以下phead-next是否还是Phead,如果是就说明此时只有哨兵节点 头删也是两种情况都是一样的代码 这里把第一个节点写为del,我们只需要让phead-next指向del,del-prev指向phead,这样就相当于把del从这个链表中断开了,接着就放心的free掉就可以了。 代码实现: //头删 void ListPopFront(List* phead) {assert(phead phead-next ! phead);List* del phead-next;del-next-prev phead;phead-next del-next;free(del);del NULL; }尾删 尾删跟头删差不多,只不过我们要找到最后一个节点(phead-prev),这就是双链表的好处 尾删的两种情况也都是一致的: End phead-prev(最后一个节点) End-prev-next phead phead-next End-prev free(End) 代码实现: //尾删 void ListPopBack(List* phead) {assert(phead phead-prev ! phead);List* End phead-prev;End-prev-next phead;phead-prev End-prev;free(End);End NULL; }在指定位置之前插入数据 如下图: 无论在什么位置之前插入元素,都是一样的代码首先我们还得写一个查找函数,这里只需要遍历找值就可以了,所以不单独写出来了,跟这里写一块了。 代码实现: //查找指定元素 List* ListFind(List* phead, LDataType x) {assert(phead phead-next ! phead);List* cur phead-next;while (cur ! phead){if (cur-val x)return cur;cur cur-next;}return NULL; }//在指定位置之前插入元素 void ListInsertFront(List* pos, LDataType x) {assert(pos);List* newNode BuyNode(x);newNode-prev pos-prev;newNode-next pos;pos-prev-next newNode;pos-prev newNode; }删除指定位置之前的数据 这里需要注意,由于我们删除的是指定位置之前的数据,所以我们要保证这个pos-prev这个位置不能是哨兵节点,同时pos-prev-prev不能为空,必须有至少两个节点才能删除指定位置之前的数据 代码实现: //删除指定位置之前的元素 void ListEarseFront(List* pos, List* phead) {assert(pos pos-prev pos-prev ! phead pos-prev-prev);List* del pos-prev;pos-prev-prev-next pos;pos-prev pos-prev-prev;free(del);del NULL; }销毁链表 销毁链表分为两种方式: (1) 由于我们是传入的phead是一级指针,而我们函数的参数也是用的一级指针接受的,因为函数的形参只是实参的一份临时拷贝,由于每次malloc的内存都是在堆区内开辟的所以我们可以做到释放每一个节点,但是phead这个指针却并不能置为空,如果不置空的话,他指向了被释放掉了的空间,还能找到那个空间,所以此时phead就是野指针,我们也只能在调用**ListDesTory()**这个销毁函数的下面手动把phead置为空。 代码实现: void ListDesTory(List* phead) {assert(phead);List* cur phead-next;while (cur ! phead){List* next cur-next;free(cur);cur next;}free(phead); }手动置空 (2) 当我们想要在函数内部修改变量的时候,我们因该传入它的地址,就像如果我们想要在函数里面修改 int a 1这个a的值,那我们应该传入的是**(a),同时我们呢要用int*** 的指针来接收,同样的这里我们呢传入**(phead),那我们就要用(List**)**来接受,这样在函数内部就可以把phead置为空了 代码实现: void ListDesTory(List** pphead) {assert(pphead *pphead);List* cur (*pphead)-next;while (cur ! (*pphead)){List* next cur-next;free(cur);cur next;}free((*pphead));*pphead NULL; }全部代码 List.h #pragma once#include stdio.h #include stdlib.h #include assert.htypedef int LDataType; typedef struct List {struct List* prev;struct List* next;LDataType val; }List;//创建哨兵节点 List* ListHeadCreat(); //打印节点 void ListPrint(List* phead); //头插 void ListPushFront(List* phead,LDataType x); //尾插 void ListPushBack(List* phead, LDataType x);//头删 void ListPopFront(List* phead); //尾删 void ListPopBack(List* phead);//查找指定元素 List* ListFind(List* phead, LDataType x); //在指定位置之前插入元素 void ListInsertFront(List* pos,LDataType x); //删除指定位置之前的元素 void ListEarseFront(List* pos, List* phead); //销毁链表 void ListDesTory(List* phead); //销毁链表 //void ListDesTory(List** pphead); List.c #define _CRT_SECURE_NO_WARNINGS#include Lish.h//创建哨兵节点 List* ListHeadCreat() {List* newhead (List*)malloc(sizeof(List));if (newhead NULL){printf(malloc fail!\n);exit(-1);}newhead-val -1;newhead-next newhead-prev newhead;return newhead; }//打印节点 void ListPrint(List* phead) {assert(phead phead-next);List* cur phead-next;while (cur ! phead){printf(%d , cur-val);cur cur-next;} }List* BuyNode(LDataType x) {List* newNode (List*)malloc(sizeof(List));if (newNode NULL){printf(malloc fail!\n);exit(-1);}newNode-val x;newNode-next newNode-prev newNode;return newNode; } //头插 void ListPushFront(List* phead, LDataType x) {assert(phead);List* newNode BuyNode(x); newNode-prev phead;newNode-next phead-next;phead-next newNode;//如果只有一个节点,要把此时的哨兵节点的上一个节点指向新插入的节点if (phead-prev phead)phead-prev newNode; } //尾插 void ListPushBack(List* phead, LDataType x) {assert(phead);List* newNode BuyNode(x);newNode-next phead;newNode-prev phead-prev;phead-prev-next newNode;phead-prev newNode; }//头删 void ListPopFront(List* phead) {assert(phead phead-next ! phead);List* del phead-next;del-next-prev phead;phead-next del-next;free(del);del NULL; } //尾删 void ListPopBack(List* phead) {assert(phead phead-prev ! phead);List* End phead-prev;End-prev-next phead;phead-prev End-prev;free(End);End NULL; }//查找指定元素 List* ListFind(List* phead, LDataType x) {assert(phead phead-next ! phead);List* cur phead-next;while (cur ! phead){if (cur-val x)return cur;cur cur-next;}return NULL; }//在指定位置之前插入元素 void ListInsertFront(List* pos, LDataType x) {assert(pos);List* newNode BuyNode(x);newNode-prev pos-prev;newNode-next pos;pos-prev-next newNode;pos-prev newNode; }//删除指定位置之前的元素 void ListEarseFront(List* pos, List* phead) {assert(pos pos-prev pos-prev ! phead pos-prev-prev);List* del pos-prev;pos-prev-prev-next pos;pos-prev pos-prev-prev;free(del);del NULL; } //销毁链表 void ListDesTory(List* phead) {assert(phead);List* cur phead-next;while (cur ! phead){List* next cur-next;free(cur);cur next;}free(phead); } 销毁链表 //void ListDesTory(List** pphead) //{ // assert(pphead *pphead); // List* cur (*pphead)-next; // while (cur ! (*pphead)) // { // List* next cur-next; // free(cur); // cur next; // } // free((*pphead)); // *pphead NULL; //}结语 OK了,链表在单链表和双向循环带头链表写完了就告一段落了,感觉有帮助的话可以点点赞,如果有哪写错了欢迎指出来~
http://www.pierceye.com/news/746049/

相关文章:

  • 网站做分布式部署湖南平台网站建设设计
  • 沈阳市建设工程项目管理中心网站网络项目网
  • 沈阳网站建设成创输入网址跳到别的网站
  • 课程网站开发建设商务网站的费用
  • 资讯网站优化排名wordpress 删除所有文章
  • 旅游海外推广网站建设方案wordpress外观无法编辑
  • 品牌手表网站网站推广律师关键词有哪些
  • 卖视频会员个人网站怎么做推广网站的图片怎么做
  • 服务器关闭 网站被k微信公众号推广的好处
  • 工业设计招聘信息网站做网站首页轮播图代码
  • 央企网站开发手机网站 input
  • 千里马招标网站东莞网站推广行者seo08
  • 网络工程专业主要学什么百度seo课程
  • 网站定制开发收费标准是多少网站导航功能
  • 东莞网站(建设信科网络)公众号小程序开发公司
  • dw网站结构图怎么做4399电脑版网页链接
  • 网站服务器网址招聘seo专员
  • 个人网站模板psd主机服务器网站 怎么做
  • 网站开发公司的义务深圳 电子商务网站开发
  • 北京外贸网站设计备案宁波网站推广专业的建站优化公司
  • 政协系统网站建设织梦手机网站
  • 网站建设上海网站制作如何修改上线网站
  • 漫画网站建设教程网站描述怎么设置
  • 网站左侧树形导航怎么做农村网站做移动
  • 建立企业网站方案php做简单网站教程
  • 一个网站交互怎么做的银行营销活动方案
  • 网站读取速度慢58同城二手房出售
  • 个人备案 网站名称 例子wordpress怎样下载
  • 郑州网络营销网站定制做网站服务
  • 学校网站英文怎么做souq网站