链表(二) 双链表操作详解

news2024/11/17 12:41:11

文章目录

  • 四、双向带头循环链表的实现
    • List.h
    • List.c
      • 创建返回链表的头结点
      • 双向链表打印
      • 双向链表尾插
      • 双向链表尾删
      • 双向链表头插
      • 双向链表头删
      • 双向链表查找
      • 双向链表在pos的前面进行插入
      • 双向链表删除pos位置的节点
  • 五、单链表与双链表比较

什么是链表及单链表的实现请跳转: 链表(一) 单链表操作详解
在这里插入图片描述

四、双向带头循环链表的实现

在这里插入图片描述

在这里插入图片描述
代码结构设计:

  • List.h: 存放链表结构及需要用到的头文件,函数声明等
  • List.c: 各种操作函数的具体实现

List.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

// 带头+双向+循环链表增删查改实现

typedef int LTDataType;

typedef struct ListNode
{
	LTDataType data;
	struct ListNode* next;
	struct ListNode* prev;
}ListNode;

// 创建返回链表的头结点.
ListNode* ListCreate();
// 双向链表打印
void ListPrint(ListNode* pHead);
// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x);
// 双向链表尾删
void ListPopBack(ListNode* pHead);
// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x);
// 双向链表头删
void ListPopFront(ListNode* pHead);
// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x);
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos);

List.c

#include "List.h"

//创建节点,此函数用于方便创建节点
ListNode* ListBuy(int x)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	if (node == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	node->data = x;
	node->next = NULL;
	node->prev = NULL;

	return node;
}

创建返回链表的头结点

ListNode* ListCreate()
{
	ListNode* head = ListBuy(0);

	head->next = head;
	head->prev = head;

	return head;
}

在这里插入图片描述

双向链表打印

void ListPrint(ListNode* pHead)
{
	assert(pHead);
	ListNode* cur = pHead->next;
	printf("head <=> ");

	while (cur != pHead)
	{
		printf("%d <=> ", cur->data);
		cur = cur->next;
	}
	printf("\n");
}

双向链表尾插

void ListPushBack(ListNode* pHead, LTDataType x)
{
	assert(pHead);

	ListNode* newNode = ListBuy(x);
	ListNode* tail = pHead->prev;

	tail->next = newNode;
	newNode->prev = tail;

	pHead->prev = newNode;
	newNode->next = pHead;
}

在这里插入图片描述

双向链表尾删

void ListPopBack(ListNode* pHead)
{
	assert(pHead);
	assert(pHead->next!=pHead);

	ListNode* tail = pHead->prev;
	ListNode* tailPrev = tail->prev;
	free(tail);

	tailPrev->next = pHead;
	pHead->prev = tailPrev;
}

在这里插入图片描述

双向链表头插

void ListPushFront(ListNode* pHead, LTDataType x)
{
	assert(pHead);

	ListNode* first = pHead->next;
	ListNode* newNode = ListBuy(x);

	pHead->next = newNode;
	newNode->prev = pHead;

	newNode->next = first;
	first->prev = newNode;
}

在这里插入图片描述

双向链表头删

void ListPopFront(ListNode* pHead)
{
	assert(pHead);
	assert(pHead->next!=pHead);

	ListNode* first = pHead->next;
	ListNode* second = pHead->next->next;
	free(first);

	pHead->next = second;
	second->prev = pHead;
}

在这里插入图片描述

双向链表查找

ListNode* ListFind(ListNode* pHead, LTDataType x)
{
	assert(pHead);

	ListNode* cur = pHead->next;

	while (cur != pHead)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

双向链表在pos的前面进行插入

void ListInsert(ListNode* pos, LTDataType x)
{
	assert(pos);

	ListNode* posPrev = pos->prev;
	ListNode* newNode = ListBuy(x);

	posPrev->next = newNode;
	newNode->prev = posPrev;

	newNode->next = pos;
	pos->prev = newNode;
}

在这里插入图片描述

双向链表删除pos位置的节点

void ListErase(ListNode* pos)
{
	assert(pos);

	ListNode* posPrev = pos->prev;
	ListNode* posNext = pos->next;
	free(pos);

	posPrev->next = posNext;
	posNext->prev = posPrev;
}

在这里插入图片描述

五、单链表与双链表比较

单链表双链表
存储空间物理上一定连续逻辑上连续,物理上不一定
随机访问支持 :O(1)不支持 :O(n)
任意位置插入删除元素可能需要搬移元素,效率低:O(N)只需修改指针指向
插入动态顺序表,空间不够时需要扩容没有容量的概念
应用场景元素高效存储+频繁访问任意位置插入和删除频繁
缓存利用率

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/831385.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JS监听页面回退前进的方案

您好&#xff0c;如果喜欢我的文章&#xff0c;可以关注我的公众号「量子前端」&#xff0c;将不定期关注推送前端好文~ 前言 在业务中遇到需求&#xff0c;App中的H5页面跳转到其他外链页面&#xff0c;外链页面修改了整个APP中的导航栏样式&#xff0c;回退到当前页面&…

微信开发之自动回复的技术实现

请求URL&#xff1a; http://域名地址/sendText 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId是string登录实例标识wcId是string接收…

人物宣传稿怎么写?写作技巧有哪些?

人物宣传稿是一种介绍个人或组织成员的文案&#xff0c;旨在宣传其成就、特点和影响力。以下是一些人物宣传稿的写作技巧&#xff0c;帮助您撰写出生动、引人入胜的宣传稿。接下来伯乐网络传媒就来给大家讲解一下。 突出核心信息&#xff1a; 在宣传稿的开头&#xff0c;用简洁…

ARTS 挑战打卡的第1天,我学到了这些~

关于 ARTS 的释义 —— 每周完成一个 ARTS&#xff1a; ● Algorithm: 每周至少做一个 LeetCode 的算法题 ●Review: 阅读并点评至少一篇英文技术文章 ● Tips: 学习至少一个技术技巧 ● Share: 分享一篇有观点和思考的技术文章 深度学习 深度学习概念崛起框架 主页传送门&…

在线思维导图怎么绘制?学学这几种绘制方法

在线思维导图怎么绘制&#xff1f;思维导图是一种非常有效的学习和工作工具&#xff0c;可以帮助我们更好地组织和呈现信息&#xff0c;提高学习效率和工作效率。而在线思维导图的出现&#xff0c;更是为我们的绘制带来了极大的便利。现在也有很多绘制思维导图的方法&#xff0…

【RedisInsight】连入Docker容器可视化redis服务

文章目录 下载安装RedisInsight添加数据库添加docker容器内的redis数据库 下载安装RedisInsight 进入redis官网下载&#xff1a;https://redis.com/redis-enterprise/redis-insight/&#xff0c;安装过程一路Next即可。 打开桌面上的快捷方式启动&#xff1a;RedisInsight-v2…

windows创建占用特定端口程序

默认情况下&#xff0c;远程桌面使用的是3389端口。如果您想将远程桌面端口更改为8005&#xff0c;以达到模拟程序占用端口8005的情况&#xff0c;可以执行以下操作&#xff1a; 如执行以下命令&#xff0c;则1&#xff0c;2&#xff0c;3步相同操作可以跳过&#xff0c;直接往…

C++ 好用的日志库--spdlog

背景 spdlog 是一个快速、异步的、header-only 的 C 日志库。它提供了简单易用的 API 并具有高性能和可扩展性。 下载和使用 下载 spdlog 库下载地址&#xff1a;github 链接 hello world 在使用时只需要 include 整个 /include/spdlog 文件夹即可。 #include "spd…

【excel技巧】进阶版:excel文件批量提取文件名

前面给大家分享了简单的excel提取文件名方法&#xff0c;今天继续分享&#xff0c;进阶版excel文件批量提取文件名的方法。 点击excel工具栏中的【数据】功能&#xff0c;点击获取数据 – 来自文件 – 从文件夹 然后找到需要提取文件名的文件夹&#xff0c;点击打开&#xff0…

直线导轨使用中常见的问题有哪些?

直线导轨作为设备的核心部件之一&#xff0c;起着导向和支撑的作用功能。目前&#xff0c;已被广泛应用在各行各业中&#xff0c;大到机械设备&#xff0c;小到抽屉&#xff0c;我们都能看到直线导轨的身影&#xff0c;可以说&#xff0c;直线导轨已经悄无声息的进入到我们的生…

OC与Swift的相互调用

OC调用Swift方法 1、在 Build Settings 搜索 Packaging &#xff0c;设置 Defines Module 为 YES 2、新建 LottieBridge.swift 文件&#xff0c;自动生成桥 ProductName-Bridging-Header.h 3、在 LottieBridge.swift 中&#xff0c;定义Swift类继承于OC类&#xff0c;声明 obj…

站点可靠性工程 (SRE)

随着世界各地的组织努力开发安全、可靠、可扩展且可持续的 IT 基础架构&#xff0c;对高效基础架构监控和管理的需求日益增长&#xff0c;企业正在用不可扩展的遗留架构换取现代解决方案&#xff0c;在尖端技术的推动下&#xff0c;这些使基础设施管理过程更加顺畅和轻松&#…

Django学习笔记-默认的用户认证系统(auth)

一、Django默认的用户认证系统 Django 自带一个用户验证系统。它负责处理用户账号、组、权限和基于cookie的用户会话。 Django 验证系统处理验证和授权。简单来说&#xff0c;验证检验用户是否是他们的用户&#xff0c;授权决定已验证用户能做什么。这里的术语验证用于指代这…

【云原生】K8S二进制搭建一

目录 一、环境部署1.1操作系统初始化 二、部署etcd集群2.1 准备签发证书环境在 master01 节点上操作在 node01与02 节点上操作 三、部署docker引擎四、部署 Master 组件4.1在 master01 节点上操 五、部署Worker Node组件 一、环境部署 集群IP组件k8s集群master01192.168.243.1…

虹科方案 | 虹科AR助力汽车产业降本增效,实现数字化转型!

虹科AR远程解决方案 将高性能的Vuzix AR眼镜与工业远程软件相结合&#xff0c;一线员工使用AR眼镜呼叫专家&#xff0c;由远程专家进行诊断并给出建议&#xff0c;支持一线员工与远程专家实时语音视频交互、AR标注指引、发送文件图片并进行会议录制&#xff0c;帮助一线员工解…

8.物联网操作系统之事件标志组

。事件标志组定义 FreeRTOS事件标志组介绍 FreeRTOS事件标志组工作原理 一。事件标志组定义 信号量信号量只能实现任务与单个事件或任务间的同步。但是某些任务可能会需要与多个事件或任务进行同步&#xff0c;此时就可以使用事件标志组来解决。事件标志组能够实现某个任务与…

opencv36-形态学操作-膨胀 cv2.dilate()

膨胀操作是形态学中另外一种基本的操作。膨胀操作和腐蚀操作的作用是相反的&#xff0c;膨胀操作能对图像的边界进行扩张。膨胀操作将与当前对象&#xff08;前景&#xff09;接触到的背景点合并到当前对象内&#xff0c;从而实现将图像的边界点向外扩张。如果图像内两个对象的…

接口测试原理和基本步骤

目录 1、接口测试原理 2、接口测试的实现 3、接口测试用例 4、接口测试工具 5、HTTP协议 6、JMeter 7、抓包 8、接口测试可以发现什么样的Bug&#xff1f; 1、接口测试原理 接口测试&#xff0c;实际上是针对于接口做测试的。 那么接口是什么&#xff1f; 软件开发&…

人力管理系统servlet+jsp人事考勤员工部门java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 人力管理系统servletjsp 系统有1权限&#xff1a;管理…

Linux - gcc/g++工具使用

gcc/g是用于编译C/C程序的编译器 1.编译过程 1. 预处理&#xff08;头文件展开&#xff0c;条件编译&#xff0c;进行宏替换&#xff0c;去注释等) 2. 编译&#xff08;C语言汇编语言) 3. 汇编&#xff08;汇编->可重定位目标二进制文件&#xff0c;不可以被执行的&#xff…