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

网站做非经营性广告需备案西安推广平台排行榜

网站做非经营性广告需备案,西安推广平台排行榜,ubc网站谁做的,企业网站安全建设方案​ 个人主页:秋风起,再归来~ 数据结构与算法 个人格言:悟已往之不谏,知来者犹可追 克心守己,律己则安! 目录 1、双向链表的结构及概念 2、双向链表的实现 2.1 要实现的接口…

                                                                                个人主页:秋风起,再归来~

                                                                                            数据结构与算法                             

                                                                       个人格言:悟已往之不谏,知来者犹可追

                                                                                        克心守己,律己则安!

目录

1、双向链表的结构及概念

2、双向链表的实现

2.1 要实现的接口(List.h)

2.2 链表的初始化

2.3 链表的销毁

2.4 链表的打印

2.5 链表的尾插

2.6 链表的尾删

2.7 链表的头插

2.8 链表的头删

2.8 链表的查找

2.9 pos位置插入数据

2.10 pos位置删除数据

3、完整代码

List.h

List.c

Test.c(本人在实现双向链表时的测试代码) 

4、 完结散花


1、双向链表的结构及概念

我们这里要实现的数据结构是带头双向循环的链表(简称双向链表)

下面就是该链表的物理模型啦~

2、双向链表的实现

2.1 要实现的接口(List.h)

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int LTDataType;
typedef struct ListNode
{struct ListNode* prev;//前驱指针LTDataType data;struct ListNode* next;//后驱指针
}LTNode;//链表的初始化
//void LTInit(LTNode** pphead);带参数的初始化
LTNode* LTInit();//链表销毁
void LTDestroy(LTNode* phead);//链表的打印
void LTPrint(LTNode* phead);//链表的尾插
void LTPushBack(LTNode* phead, LTDataType x);//链表的尾删
void LTPopBack(LTNode* phead);//链表的头插
void LTPushFront(LTNode* phead, LTDataType x);//链表的头删
void LTPopFront(LTNode* phead);//在双向链表中查找数据
LTNode* LTFind(LTNode* phead, LTDataType x);//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x);//删除pos位置节点
void LTErase(LTNode* pos);

2.2 链表的初始化

注意:在初始化的时候一定要让头结点的prev指针和next指针都指向自己!

//链表的初始化
//void LTInit(LTNode** pphead);带参数的初始化
LTNode* LTInit()
{//初始化时创建一个带哨兵卫的头结点LTNode* phead = (LTNode*)malloc(sizeof(LTNode));if (phead == NULL){perror("malloc fail!\n");return NULL;}phead->next = phead->prev = phead;phead->data = -1;return phead;
}

2.3 链表的销毁

注意:我们一定是从链表的头结点(头结点中并没有有效数据的存储)的下一个位置开始销毁链表的!

//链表销毁
void LTDestroy(LTNode* phead)
{assert(phead);LTNode* pcur=phead->next;LTNode* next = NULL;//结束条件是当pcur不等于篇pheadwhile (pcur!=phead){next = pcur->next;free(pcur);pcur = next;}
}

并且我们在调用链表的销毁函数后依然要手动释放动态内存开辟的phead头结点 !

为尽量确保接口传递参数的一致性我们并没有传递头结点的地址,所以我们并不能在链表的销毁函数中free我们的头结点!

LTDestroy(plist);
//动态开辟的头结点需要手动释放
free(plist);
plist = NULL;

2.4 链表的打印

遍历链表打印头结点,循环结束的条件是pcur=phead,继续的条件是pcur!=phead

//链表的打印
void LTPrint(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;LTNode* next = NULL;//结束条件是当pcur不等于篇pheadwhile (pcur != phead){next = pcur->next;printf("%d->", pcur->data);pcur = next;}printf("\n");
}

2.5 链表的尾插

新节点的创建(单独封装成为一个函数)

//新节点的创建
LTNode* ListCreatNode(LTDataType x)
{LTNode* NewNode = (LTNode*)malloc(sizeof(LTNode));//开辟空间if (NewNode == NULL)//判断空间是否开辟成功{perror("malloc fail");return NULL;}NewNode->data = x;//赋值NewNode->next = NULL;//置空NewNode->prev = NULL;return NewNode;
}

链表的尾插 (在为尾插接口中直接调用创建节点的函数)

//链表的尾插
void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newNode = ListCreatNode(x);//先创建一个新节点LTNode* tail = phead->prev;newNode->prev = tail;newNode->next = phead;tail->next = newNode;phead->prev = newNode;
}

2.6 链表的尾删

注意各个节点的指向!

//链表的尾删
void LTPopBack(LTNode* phead)
{//尾删的前提是双向链表不为空assert(phead && phead->next != phead);LTNode* tail = phead->prev;phead->prev = tail->prev;tail->prev->next=phead;free(tail);tail = NULL;
}

2.7 链表的头插

//链表的头插
void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newNode = ListCreatNode(x);//先创建一个新节点newNode->next = phead->next;newNode->prev = phead;phead->next->prev = newNode;phead->next = newNode;
}

2.8 链表的头删

//链表的头删
void LTPopFront(LTNode* phead)
{//头删的前提是双向链表不为空assert(phead && phead->next != phead);LTNode* start = phead->next;phead->next = start->next;start->next->prev = phead;free(start);start= NULL;
}

2.8 链表的查找

返回值是该指向该数据节点的结构体指针,如没有找到,直接返回空!

//在双向链表中查找数据
LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* pcur = phead->next;LTNode* next = NULL;//结束条件是当pcur不等于篇pheadwhile (pcur != phead){if (pcur->data == x){return pcur;}next = pcur->next;pcur = next;}return NULL;
}

2.9 pos位置插入数据

//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newNode = ListCreatNode(x);//先创建一个新节点newNode->next = pos->next;newNode->prev = pos;pos->next->prev = newNode;pos->next = newNode;
}

2.10 pos位置删除数据

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

3、完整代码

List.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int LTDataType;
typedef struct ListNode
{struct ListNode* prev;//前驱指针LTDataType data;struct ListNode* next;//后驱指针
}LTNode;//链表的初始化
//void LTInit(LTNode** pphead);带参数的初始化
LTNode* LTInit();//链表销毁
void LTDestroy(LTNode* phead);//链表的打印
void LTPrint(LTNode* phead);//链表的尾插
void LTPushBack(LTNode* phead, LTDataType x);//链表的尾删
void LTPopBack(LTNode* phead);//链表的头插
void LTPushFront(LTNode* phead, LTDataType x);//链表的头删
void LTPopFront(LTNode* phead);//在双向链表中查找数据
LTNode* LTFind(LTNode* phead, LTDataType x);//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x);//删除pos位置节点
void LTErase(LTNode* pos);

List.c

#include"List.h"//链表的初始化
//void LTInit(LTNode** pphead);带参数的初始化
LTNode* LTInit()
{//初始化时创建一个带哨兵卫的头结点LTNode* phead = (LTNode*)malloc(sizeof(LTNode));if (phead == NULL){perror("malloc fail!\n");return NULL;}phead->next = phead->prev = phead;phead->data = -1;return phead;
}//链表销毁
void LTDestroy(LTNode* phead)
{assert(phead);LTNode* pcur=phead->next;LTNode* next = NULL;//结束条件是当pcur不等于篇pheadwhile (pcur!=phead){next = pcur->next;free(pcur);pcur = next;}
}//链表的打印
void LTPrint(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;LTNode* next = NULL;//结束条件是当pcur不等于篇pheadwhile (pcur != phead){next = pcur->next;printf("%d->", pcur->data);pcur = next;}printf("\n");
}//新节点的创建
LTNode* ListCreatNode(LTDataType x)
{LTNode* NewNode = (LTNode*)malloc(sizeof(LTNode));//开辟空间if (NewNode == NULL)//判断空间是否开辟成功{perror("malloc fail");return NULL;}NewNode->data = x;//赋值NewNode->next = NULL;//置空NewNode->prev = NULL;return NewNode;
}//链表的尾插
void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newNode = ListCreatNode(x);//先创建一个新节点LTNode* tail = phead->prev;newNode->prev = tail;newNode->next = phead;tail->next = newNode;phead->prev = newNode;
}//链表的尾删
void LTPopBack(LTNode* phead)
{//尾删的前提是双向链表不为空assert(phead && phead->next != phead);LTNode* tail = phead->prev;phead->prev = tail->prev;tail->prev->next=phead;free(tail);tail = NULL;
}//链表的头插
void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newNode = ListCreatNode(x);//先创建一个新节点newNode->next = phead->next;newNode->prev = phead;phead->next->prev = newNode;phead->next = newNode;
}//链表的头删
void LTPopFront(LTNode* phead)
{//头删的前提是双向链表不为空assert(phead && phead->next != phead);LTNode* start = phead->next;phead->next = start->next;start->next->prev = phead;free(start);start= NULL;
}//在双向链表中查找数据
LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* pcur = phead->next;LTNode* next = NULL;//结束条件是当pcur不等于篇pheadwhile (pcur != phead){if (pcur->data == x){return pcur;}next = pcur->next;pcur = next;}return NULL;
}//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newNode = ListCreatNode(x);//先创建一个新节点newNode->next = pos->next;newNode->prev = pos;pos->next->prev = newNode;pos->next = newNode;
}//删除pos位置节点
void LTErase(LTNode* pos)
{assert(pos);pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;
}

Test.c(本人在实现双向链表时的测试代码) 

#define _CRT_SECURE_NO_WARNINGS#include"LIst.h"void TestList1()
{LTNode* plist;plist = LTInit();//初始化链表LTPushBack(plist,1);LTPushBack(plist,2);LTPushBack(plist,3);LTPushFront(plist, 4);LTPushFront(plist, 4);/*LTPopFront(plist);LTPopFront(plist);*/LTNode* pos=LTFind(plist, 2);printf("删除pos位置之前\n");LTPrint(plist);LTErase(pos);printf("删除pos位置之后\n");LTPrint(plist);//LTInsert(pos, 5);//LTPopBack(plist);//LTPopBack(plist);//LTPopBack(plist);LTDestroy(plist);//动态开辟的头结点需要手动释放free(plist);plist = NULL;
}int main()
{TestList1();return 0;
}

4、 完结散花

好了,这期的分享到这里就结束了~

如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~

如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~

我们下期不见不散~~

http://www.ds6.com.cn/news/38745.html

相关文章:

  • 如何用ps做网站ui百度云搜索引擎入口官方
  • 建设企业网站都需要啥提高网站排名的软件
  • 周村网站制作首选公司电商怎么做推广
  • 白鹭引擎做网站百度云app
  • 网站建设需要些什么软件谷歌首页
  • 电子商务平台经营者对于竞价排名的商品或服务企业seo的措施有哪些
  • 信阳电子商务网站建设外贸网络营销推广
  • 创意江苏网站建设百度指数电脑版
  • 网站建设有用吗青岛网站建设微动力
  • 缩我短链接生成器泰安seo培训
  • 做最简单的网站爱站网官网查询域名
  • 手机购物网站制作数字化营销怎么做
  • 网站建设要注意那些问题什么是网站推广策略
  • 网站页眉设计线上如何做推广
  • 湖南交通建设监理协会网站站长工具seo综合查询5g
  • 好看的手机网站模板免费下载什么叫seo
  • 凡科建设网站别人能进去么百度信息流广告
  • 商丘做网站公司网络营销服务工具
  • 个人写真与艺术照的区别在哪广州网站优化关键词排名
  • 多说评论插件对网站优化广告推广平台赚取佣金
  • 南昌建设网站免费可用的网站源码
  • 帮一个企业做网站流程武汉seo首页
  • 近期做网站需要什么软件百度网站下拉排名
  • 网站建设赠送seo百度优化点击软件
  • 建商城网站需要什么杭州seo排名收费
  • 柳州企业网站制作哪家好南宁百度seo排名
  • 免费投资办厂河南网站推广优化排名
  • 自学网站开发流程百度广告公司联系方式
  • 全套网站搭建百度网址输入
  • 芜湖市建设办网站泉州seo托管