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

微网站建设教程浙江省建设执业资格中心网站

微网站建设教程,浙江省建设执业资格中心网站,怎么仿照别人网站,小程序开发 上海引言 用动态的方式实现双向链表的注意接口,以代码注释为主。 一、什么是双向链表 单向链表是可以向后依次遍历每个元素,双向链表是既可以依次向后遍历每个元素,也可以依次向前,遍历每个元素。 有了单链表的实现,双向链…

引言

        用动态的方式实现双向链表的注意接口,以代码注释为主。

一、什么是双向链表

        单向链表是可以向后依次遍历每个元素,双向链表是既可以依次向后遍历每个元素,也可以依次向前,遍历每个元素。

        有了单链表的实现,双向链表的实现是很类似的。

        注意:这里是实现的是带“哨兵位”的双向链表,即带头双向循环链表。也有不带头的双向循环链表,可以自己尝试尝试。

、动态双向链表模拟实现

分3个文件:

List.c  //双链表的主要代码(核心)
List.h  //双链表的函数的声明
test.c  //测试代码

1、双链表的结构

定义在List.h文件中

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
//双链表的结构:
typedef int LTDataType;
typedef struct ListNode
{LTDataType data;      //存储的数据struct ListNode* next;//指向前一个地址的指针struct ListNode* prev;//指向下一个地址的指针
}LTNode;

2、申请新结点,初始化哨兵位

LTNode* LTBuyNode(LTDataType x)  //申请新结点
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = newnode->prev = newnode; //结点自己指向自己return newnode;
}LTNode* LTInit() //初始化哨兵位
{LTNode* phead = LTBuyNode(-1); //将哨兵位的值设置成无效的值return phead;
}

3、尾插,头插

小提示:先修改新结点的指针,再修改原链表的指针

以理解为主,不用记忆代码

//尾插
void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);newnode->prev = phead->prev;  //新结点的前驱指向最后一个结点newnode->next = phead;        //新结点的后驱指向哨兵位phead->prev->next = newnode;  //先找到原链表的最后一个结点,将其后驱改成新结点的地址phead->prev = newnode;        //最后将哨兵位的前驱指向新结点(即最后一行结点)
}
//头插
void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);newnode->next = phead->next;newnode->prev = phead;phead->next->prev = newnode;phead->next = newnode;
}

4、打印,判断链表是否为空

void LTPrint(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;  //指向第一个结点while (pcur != phead)    //回到哨兵位时,结束打印{printf("%d->", pcur->data);pcur = pcur->next;    //依次向后找结点,打印结点内容}printf("\n");
}//判断有无元素
bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;  //当哨兵位自己指向自己说明没有元素,链表为空,否则,链表里面就是有元素的
}

5、尾删,头删

//尾删
void LTPopBack(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->prev; //拿到尾结点del->prev->next = phead;   //修改尾结点前一个结点的后驱phead->prev = del->prev;   //修改头结点的前驱free(del);del = NULL;
}
//头删
void LTPopFront(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->next;del->next->prev = phead;  //修改头结点的下一个结点的前驱phead->next = del->next;  //修改头结点的后驱free(del);del = NULL;
}

6、查找

//查找
LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead)  //依次向后遍历链表{if (pcur->data == x){return pcur;   //找到返回结点的地址}pcur = pcur->next;}return NULL; //没有就返回NULL
}

7、在pos位置前或后插入数据

//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = LTBuyNode(x);newnode->prev = pos;newnode->next = pos->next;pos->next->prev = newnode;pos->next = newnode;
}//在pos位置前插入数据
void LTInsertAfter(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = LTBuyNode(x);newnode->next = pos;newnode->prev = pos->prev;pos->prev->next = newnode;pos->prev = newnode;
}

8、删除pos位置的结点

//删除pos位置的结点
void LTErase(LTNode* pos)
{assert(pos);pos->next->prev = pos->prev;pos->prev->next = pos->next;free(pos);pos = NULL;
}

9、销毁双向链表

销毁双向链表(法一:因为要对头节点做修改,传二级指针)
void LTDesTroy(LTNode** pphead)
{assert(pphead);LTNode* pcur = (*pphead)->next;while (pcur != *(pphead)){LTNode* next = pcur->next;free(pcur);pcur = next;}free(*pphead);*pphead = NULL;
}
//销毁双向链表(法二:为了保持代码的统一性,这里也传一级指针,但是调用完函数后需要手动将头结点置为NULL;)
void LTDesTroy(LTNode* phead)
{assert(phead);LTNode* pcur = phead;while (pcur != phead){LTNode* next = pcur->next;free(pcur);pcur = next;}
}

三、所以代码

        说白了:双向链表的实现和修改就是对结点地址的修改,只要想明白了,是很简单的

1、List.h中的代码:

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
//双链表的结构:
typedef int LTDataType;
typedef struct ListNode
{LTDataType data;      //存储的数据struct ListNode* next;//指向前一个地址的指针struct ListNode* prev;//指向下一个地址的指针
}LTNode;void LTPrint(LTNode* phead);LTNode* LTInit();
//尾插
void LTPushBack(LTNode* phead, LTDataType x);
//头插
void LTPushFront(LTNode* phead, LTDataType x);//判断有无元素
bool LTEmpty(LTNode* phead);//尾删
void LTPopBack(LTNode* phead);
//头删
void LTPopFront(LTNode* phead);//查找
LTNode* LTFind(LTNode* phead, LTDataType x);//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x);
//在pos位置前插入数据
void LTInsertAfter(LTNode* pos, LTDataType x);//删除pos位置的结点
void LTErase(LTNode* pos);//销毁双向链表(法一:因为要对头节点做修改,传二级指针)
//void LTDesTroy(LTNode** pphead);//销毁双向链表(法二:为了保持代码的统一性,这里也传一级指针,但是调用完函数后需要手动将头结点置为NULL;)
void LTDesTroy(LTNode* phead);

2、List.c中的代码

#define _CRT_SECURE_NO_WARNINGS
#include"List.h"
LTNode* LTBuyNode(LTDataType x)  //申请新结点
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = newnode->prev = newnode; //结点自己指向自己return newnode;
}LTNode* LTInit() //初始化哨兵位
{LTNode* phead = LTBuyNode(-1); //将哨兵位的值设置成无效的值return phead;
}void LTPrint(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;  //指向第一个结点while (pcur != phead)    //回到哨兵位时,结束打印{printf("%d->", pcur->data);pcur = pcur->next;    //依次向后找结点,打印结点内容}printf("\n");
}
//尾插
void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);newnode->prev = phead->prev;  //新结点的前驱指向最后一个结点newnode->next = phead;        //新结点的后驱指向哨兵位phead->prev->next = newnode;  //先找到原链表的最后一个结点,将其后驱改成新结点的地址phead->prev = newnode;        //最后将哨兵位的前驱指向新结点(即最后一行结点)
}
//头插
void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);newnode->next = phead->next;newnode->prev = phead;phead->next->prev = newnode;phead->next = newnode;
}//判断有无元素
bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;  //当哨兵位自己指向自己说明没有元素,链表为空,否则,链表里面就是有元素的
}//尾删
void LTPopBack(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->prev; //拿到尾结点del->prev->next = phead;   //修改尾结点前一个结点的后驱phead->prev = del->prev;   //修改头结点的前驱free(del);del = NULL;
}
//头删
void LTPopFront(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->next;del->next->prev = phead;  //修改头结点的下一个结点的前驱phead->next = del->next;  //修改头结点的后驱free(del);del = NULL;
}
//查找
LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead)  //依次向后遍历链表{if (pcur->data == x){return pcur;   //找到返回结点的地址}pcur = pcur->next;}return NULL; //没有就返回NULL
}
//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = LTBuyNode(x);newnode->prev = pos;newnode->next = pos->next;pos->next->prev = newnode;pos->next = newnode;
}//在pos位置前插入数据
void LTInsertAfter(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = LTBuyNode(x);newnode->next = pos;newnode->prev = pos->prev;pos->prev->next = newnode;pos->prev = newnode;
}
//删除pos位置的结点
void LTErase(LTNode* pos)
{assert(pos);pos->next->prev = pos->prev;pos->prev->next = pos->next;free(pos);pos = NULL;
}//销毁双向链表(法一:因为要对头节点做修改,传二级指针)
//void LTDesTroy(LTNode** pphead)
//{
//	assert(pphead);
//	LTNode* pcur = (*pphead)->next;
//	while (pcur != *(pphead))
//	{
//		LTNode* next = pcur->next;
//		free(pcur);
//		pcur = next;
//	}
//	free(*pphead);
//	*pphead = NULL;
//}void LTDesTroy(LTNode* phead)
{assert(phead);LTNode* pcur = phead;while (pcur != phead){LTNode* next = pcur->next;free(pcur);pcur = next;}
}

3、测试时的代码(test.c中):

#include"List.h"int main()
{LTNode* plist = LTInit();LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);/*LTPushFront(plist, 3);if (LTFind(plist, 2)){printf("找到了\n");}else{printf("无\n");}*///LTInsert(LTFind(plist, 3), 4);//LTInsertAfter(LTFind(plist, 3), 4);//LTErase(LTFind(plist, 2));LTPrint(plist);LTDesTroy(plist);plist = NULL;return 0;
}


文章转载自:

http://UOcul8cs.dxzcr.cn
http://WAnRuaho.dxzcr.cn
http://HjF3Apzb.dxzcr.cn
http://hM2XqJm4.dxzcr.cn
http://wKmaSt2q.dxzcr.cn
http://1Ri3aSh8.dxzcr.cn
http://V9sitSjx.dxzcr.cn
http://2lJgwtle.dxzcr.cn
http://jPaYUWKi.dxzcr.cn
http://ohTipGDm.dxzcr.cn
http://o03zaHTg.dxzcr.cn
http://uYd9W8qd.dxzcr.cn
http://f5kOJEph.dxzcr.cn
http://zUUa8QSp.dxzcr.cn
http://1hgOwJap.dxzcr.cn
http://V9QGvTTP.dxzcr.cn
http://rwMufNOp.dxzcr.cn
http://OcPH79jh.dxzcr.cn
http://fv1EZbpI.dxzcr.cn
http://Ghf8xSDs.dxzcr.cn
http://bBgt1tHw.dxzcr.cn
http://gsvhLO1N.dxzcr.cn
http://97oluBBW.dxzcr.cn
http://tir3lDCM.dxzcr.cn
http://k9XzyUMf.dxzcr.cn
http://NJBWtnv5.dxzcr.cn
http://2yF5TF5Z.dxzcr.cn
http://9AfsUdm7.dxzcr.cn
http://3EkPGXrI.dxzcr.cn
http://Tcb8xxsY.dxzcr.cn
http://www.dtcms.com/wzjs/769190.html

相关文章:

  • 为公司做的图可以上传网站吗网站做响应式还是移动端
  • 怎么做qq代挂网站百度seo关键词优化推荐
  • 广州网站建设报价单邢台做移动网站费用
  • 手机网站一键导航代码自己怎么健网站视频教程
  • 建设一个网站价格介绍国外的网站有什么不同
  • 无锡企业网站的建设温州网站推广好不好
  • wordpress设置网站首页恒美广告公司
  • 在线申请网站tdk优化文档
  • 做网站先学什么国内设计好的网站案例
  • 北京免费建站网络营销网站建设 项目要求
  • 专业的外贸行业网站开发海外转运网站建设
  • 数据库与网站建设的关系上海seo网站优化软件
  • 网站是指什么常用博客建站程序
  • 最近网站不收录企业退休做认证进哪个网站
  • 大学生做网站兼职网站建设属于什么合同
  • 企业网站尺寸网站开发进度管理表
  • 郑州网站建设七彩科技建设电子商务网站的好处
  • 怎么做国外的网站 卖东西wordpress文章目录树
  • 深圳罗湖网站设计公司价格南江移动网站建设
  • 微信彩票网站网站建设如何在南美做网站推广
  • 网站建设的费用包括哪些内容如何申请免费企业邮箱
  • 免费网站推广入口上海建设工程检测登记的网站
  • .tv可以做门户网站不建设一个商城式网站可以吗
  • 软文发布网站网站域名解绑
  • 手工艺品网站建设侧胡顺昆明seo排名外包
  • 中国建设银行互联网网站贡井移动网站建设
  • 网站图标在哪里修改360免费wifi官网
  • 北京动力 网站建设网站开发在无形资产中
  • 私人网站制作 个人使用洛阳霞光网络建站
  • 温州建站费用建设公司董事长致辞网站范文