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

做网站是先做界面还是先做后台网站引流推广

做网站是先做界面还是先做后台,网站引流推广,免费影视网站入口大全,vi设计公司 成都​ 个人主页:秋风起,再归来~ 数据结构与算法 个人格言:悟已往之不谏,知来者犹可追 克心守己,律己则安! 目录 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.fp688.cn/news/159164.html

相关文章:

  • 无锡哪家做网站好sem竞价培训
  • wordpress做出影视网站seo教程网
  • 笨鸟网站开发电话百度
  • 专业做网站app的公司百度提升排名
  • 宁波网站设计一手app推广接单平台
  • 外贸商城网站制作公司深圳网站设计公司排行
  • 代做网站推广的公司关键词推广软件排名
  • 唐山seo网络推广手机网络优化
  • 有人找做网站的大数据下的精准营销
  • sap软件金昌网站seo
  • 俄语网站建设360搜索引擎的特点
  • seo专业技术培训谷歌广告优化
  • 网站兼容代码绍兴seo排名收费
  • 网站建设服务器常用的网络营销推广方法有哪些
  • 临安做网站艺考培训学校
  • p2p商城网站建设什么是软文营销
  • 无锡网站建设解决方案企业seo顾问
  • 鸡泽网站建设开发做一个网站需要多少钱
  • 自助下单网站千峰培训
  • 杭州自助建站模板关键词优化是什么意思?
  • 用顶级域名做网站好吗管理微信软件
  • 大英哪里有做网站的济南做seo外包
  • 越南做购物网站营销型高端网站建设
  • 怎样做班级网站seo是什么服务
  • weirdcore制作网站引流获客工具
  • 做外贸网站包括哪些怎么免费做网站
  • 国别网站定位命令 co .uk sa百度电话怎么转人工客服
  • 优秀个人网站案例全国新增确诊病例
  • 网站建设视频vs桂林seo顾问
  • 我想给别人做网站制作网站需要的技术与软件