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

个人网站建设多少钱设计网站

个人网站建设多少钱,设计网站,衣服网站功能,免费素材网站哪个最好文章目录1.双链表的概念1.1概念1.2单链表与双链表的区别1.3双链表为空的情况2.双链表的功能3.双链表功能的实现3.1双链表的结构3.2初始化3.3销毁3.4链表的打印3.5判断链表是否为空3.6尾插3.7头插3.8尾删3.9头删3.10查找指定数据3.11在指定位置之后(前)插入3.12删除指定位置的节…

文章目录

  • 1.双链表的概念
    • 1.1概念
    • 1.2单链表与双链表的区别
    • 1.3双链表为空的情况
  • 2.双链表的功能
  • 3.双链表功能的实现
    • 3.1双链表的结构
    • 3.2初始化
    • 3.3销毁
    • 3.4链表的打印
    • 3.5判断链表是否为空
    • 3.6尾插
    • 3.7头插
    • 3.8尾删
    • 3.9头删
    • 3.10查找指定数据
    • 3.11在指定位置之后(前)插入
    • 3.12删除指定位置的节点
  • 4.完整代码
    • List.h
    • List.c
    • main.c
    • 运行结果

1.双链表的概念

1.1概念

双链表,即带头双向循环链表(链表有头节点,方相是双向的,且是循环的):它是一种逻辑结构为线性,物理结构不一定为线性的存储结构(与单链表基本一致)

1.2单链表与双链表的区别

  • 双链表相比单链表,新增了一个指针变量prev,用来指向前一个节点
  • 单链表中尾节点的next指针为空,而双链表中尾节点的next指针指向头节点,头节点的prev指针指向尾节点
  • 单链表是单向不循环的,而双链表是双向循环的
  • 单链表和双链表的头节点本质上是不同的,单链表中的“头节点” 由于存储了val值,所以 不是真正的头节点,仅用来表示第一个节点;而 双链表中的头节点 不存储有效数据val,只存储prev指针和next指针,所以这里的头节点 才是真正意义上的头节点,我们也可以把它称作“哨兵位”(表示只用来放哨,占一个位置,而不存储任何有效数据的节点)

综上,单链表是不带头单向不循环链表,双链表是带头双向循环链表
请添加图片描述

1.3双链表为空的情况

val中不存储有效数据,头指针head的next和prev指针都指向自己
请添加图片描述

2.双链表的功能

功能与单链表相似,同样可以概括为增删查改四个功能,但由于双链表增加了prev指针,所以可以大幅减小时间复杂度,提高代码效率

3.双链表功能的实现

3.1双链表的结构

typedef int LTDataType;//存储的数据类型
typedef struct ListNode{LTDataType val;//存储的数据struct ListNode* next;//指向后一个节点struct ListNode* prev;//指向前一个节点
}LTNode;

3.2初始化

创建一个空链表,添加一个头节点,它的next和prev指针都指向自己,其中不存储有效数据

这里我们需要先实现一个专门用来添加节点的函数

//添加节点
LTNode* LTBuyNode(int x)
{LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));if(newNode == NULL){perror("Malloc Failed!\n");exit(1);}newNode->val = x;newNode->next = newNode->prev = newNode;return newNode;
}

初始化函数:

LTNode* LTInit(void)
{//添加头节点 传入无效数据-1LTNode* phead = LTBuyNode(-1);return phead;
}

3.3销毁

遍历并删除头节点后的每一个节点

void LTDestroy(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;while(pcur != phead)//pcur==phead时即为只有一个头节点的情况{LTNode* next = pcur->next;free(pcur);pcur = next;}free(phead);//phead = NULL;//函数是传值调用(传指针本身 没有传它的地址) 因此这一步没有意义
}

注:使用此函数后,要手动把头指针赋值为NULL,避免野指针的出现

3.4链表的打印

遍历头节点之后的所有节点,一个一个打印,直到当前节点的next指向头节点

void LTPrint(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;if(pcur != phead) printf("%d", pcur->val);pcur = pcur->next;while(pcur != phead){printf(" -> %d", pcur->val);pcur = pcur->next;}printf("\n");
}

3.5判断链表是否为空

bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;
}

3.6尾插

双链表是循环的,通过head->prev找到尾节点,把新节点放到尾节点后即可

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;
}

注意:要先更新新节点的prev和next指针,如果先更新其他节点,那么再赋值给新节点,会出现错误

3.7头插

把新节点添加到头节点和第一个节点之间即可

void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newNode = LTBuyNode(x);newNode->next = phead->next;newNode->prev = phead;phead->next = newNode;newNode->next->prev = newNode;
}

3.8尾删

通过head->prev节点找到尾节点,删除即可

void LTPopBack(LTNode* phead)
{//判断链表是否为空assert(!LTEmpty(phead));LTNode* del = phead->prev;del->prev->next = phead;phead->prev = del->prev;free(del);del = NULL;
}

3.9头删

删除头节点和第一个节点之间的节点即可

void LTPopFront(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->next;del->next->prev = phead;phead->next = del->next;free(del);del = NULL;
}

3.10查找指定数据

遍历整个链表,直到节点数据值与指定数据值相等,返回该节点地址

LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* pcur = phead->next;while(pcur != phead){if(pcur->val == x) return pcur;pcur = pcur->next;}return NULL;
}

3.11在指定位置之后(前)插入

在pos之后插入:

void LTInsertAfter(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newNode = LTBuyNode(x);newNode->next = pos->next;newNode->prev = pos;pos->next->prev = newNode;pos->next = newNode;
}

在pos之前插入:

void LTInsertBefore(LTNode* pos, LTDataType x)
{assert(pos);//即为在pos前一个节点之后插入LTInsertAfter(pos->prev, x);
}

3.12删除指定位置的节点

void LTDeletePos(LTNode* pos)
{assert(pos);pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);//pos = NULL;
}

注意:pos是传值调用,在函数内不能改变它的值,所以使用该函数时,记得在函数外把pos置为NULL

4.完整代码

List.h

//  List.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>//双链表的结构
typedef int LTDataType;
typedef struct ListNode{LTDataType val;struct ListNode* next;struct ListNode* prev;
}LTNode;//添加节点
LTNode* LTBuyNode(int x);
//初始化
LTNode* LTInit(void);
//销毁
void LTDestroy(LTNode* phead);
//打印
void LTPrint(LTNode* phead);
//判空
bool LTEmpty(LTNode* phead);//尾插
void LTPushBack(LTNode* phead, LTDataType x);
//头插
void LTPushFront(LTNode* phead, LTDataType x);//尾删
void LTPopBack(LTNode* phead);
//头删
void LTPopFront(LTNode* phead);//查找
LTNode* LTFind(LTNode* phead, LTDataType x);//在指定节点之后插入
void LTInsertAfter(LTNode* pos, LTDataType x);
//在指定节点之前插入
void LTInsertBefore(LTNode* pos, LTDataType x);//删除指定节点
void LTDeletePos(LTNode* pos);

List.c

//  List.c
#include "List.h"LTNode* LTBuyNode(int x)
{LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));if(newNode == NULL){perror("Malloc Failed!\n");exit(1);}newNode->val = x;newNode->next = newNode->prev = newNode;return newNode;
}
LTNode* LTInit(void)
{//添加头节点 传入无效数据-1LTNode* phead = LTBuyNode(-1);return phead;
}
void LTDestroy(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;while(pcur != phead)//pcur==phead时即为只有一个头节点的情况{LTNode* next = pcur->next;free(pcur);pcur = next;}free(phead);//phead = NULL;//函数是传值调用(传指针本身 没有传它的地址) 因此这一步没有意义
}
void LTPrint(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;if(pcur != phead) printf("%d", pcur->val);pcur = pcur->next;while(pcur != phead){printf(" -> %d", pcur->val);pcur = pcur->next;}printf("\n");
}
bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;
}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 = newNode;newNode->next->prev = newNode;
}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->val == x) return pcur;pcur = pcur->next;}return NULL;
}void LTInsertAfter(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newNode = LTBuyNode(x);newNode->next = pos->next;newNode->prev = pos;pos->next->prev = newNode;pos->next = newNode;
}
void LTInsertBefore(LTNode* pos, LTDataType x)
{assert(pos);//即为在pos前一个节点之后插入LTInsertAfter(pos->prev, x);
}void LTDeletePos(LTNode* pos)
{assert(pos);pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);//pos = NULL;
}

main.c

#include "List.h"void test(void)
{LTNode* plist = LTInit();LTPrint(plist);LTPushBack(plist, 1);LTPrint(plist);LTPushBack(plist, 2);LTPrint(plist);LTPushFront(plist, 3);LTPrint(plist);LTPushFront(plist, 4);LTPrint(plist);printf("%p\n", LTFind(plist, 1));printf("%p\n", LTFind(plist, 5));LTInsertAfter(LTFind(plist, 4), 400);LTPrint(plist);LTInsertBefore(LTFind(plist, 2), 200);LTPrint(plist);LTPopFront(plist);LTPrint(plist);LTPopBack(plist);LTPrint(plist);LTNode* pos = LTFind(plist, 200);LTDeletePos(pos);pos = NULL;LTPrint(plist);LTDestroy(plist);plist = NULL;
}
int main(void)
{test();return 0;
}

运行结果

请添加图片描述

http://www.dtcms.com/wzjs/475700.html

相关文章:

  • 在日本网站做推广seo优化网站快速排名
  • 汽车之家 网站建设平台推广销售话术
  • 济南网站seo外包深圳市网络seo推广平台
  • 如何做门户网站今日热搜新闻头条
  • 做展示型网站便宜吗平台推广方式方法是什么
  • 360检测网站开发语言的工具百度搜索资源平台官网
  • 黄村做网站哪家好百度seo优化怎么做
  • 怎么做网站赚钱软件b站推广网站2022
  • 手机软件平台开发seo中国
  • 网站页脚需要放什么宁波企业seo服务
  • 做门窗网站怎么做阿里云注册域名
  • 企业网站建设三网合一如何对网站进行推广
  • 网站代付系统怎么做云南网络营销公司
  • wordpress购物车系统如何做一个网站的seo
  • 上海做网站的公seo是什么意思职业
  • 专业做网站安全的sine安重庆seo怎么样
  • 镇江建设网站的公司南京seo优化推广
  • 山东建设厅官方网站一级建造师5g网络优化
  • 这是我自己做的网站seo咨询常德
  • 虎扑的网站是用什么技术做的站长之家 seo查询
  • 爱客crm软件下载网站关键词优化排名外包
  • 如何建立网站站点搜索引擎排名优化seo课后题
  • wordpress 微信 登陆地址seo人员的相关薪资
  • 一元云购 网站开发全网营销推广 好做吗
  • 做家电选招标采购哪一个网站好台州关键词优化推荐
  • 网站建设修改教程视频新闻今日头条最新消息
  • 做刀模线网站网络营销策略内容
  • 做海报去哪个网站找素材比较好呢免费google账号注册入口
  • 济南工装定制公司搜索引擎优化概述
  • 手机网站 分享网络推广运营