数据结构笔记第3篇:双向链表

1、双向链表的结构

注意:这里的 "带头" 跟前面我们说的 "头结点" 是两个概念,实际前面的在单链表阶段称呼不严谨,但是为了同学们更好的理解就直接称为单链表的头结点。

带头链表里的头结点,实际为 "哨兵位" ,哨兵位节点不存储任何有效元素,只是站在这里 "放哨的"。

"哨兵位" 存在的意义:

遍历循环链表避免死循环。

注意:双向链表中,哨兵位的下一个节点是链表的第一个节点(头结点)。哨兵位的前一个节点是链表的最后一个节点(尾结点)。所以双向链表的头插是在哨兵位的后面插入数据。尾插则是在哨兵位之前插入数据。

哨兵位是作为头结点和尾结点的中点,是头结点的起点也是尾节点的终点。这样解释更容易理解。

2、 双向链表的实现

List.h 链表函数链表节点类型的声明:

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLDataType;
typedef struct ListNode
{SLDataType data;//存储数据struct ListNode* prve;//存储前一个节点的地址struct ListNode* next;//存储下一个节点的地址
}SList;
SList* SLInit();void SLPushBack(SList* phead, SLDataType x);//尾插
void SLPrint(SList* phead);//显示链表数据
void SLPustFront(SList* phead, SLDataType x);//头插
void SLPopBack(SList* phead);//尾删
void SLPopFront(SList* phead);//头删
void SLInsert(SList* pos, SLDataType x);//指定位置插入
SList* SLfind(SList* phead, SLDataType x);//查找节点
void SLEarse(SList* pos);//指定位置删除
void SLDestory(SList** pphead);//链表销毁

List.c 链表函数的实现:

#include "List.h"
//链表初始化
SList* SLInit()
{SList* phead = (SList*)malloc(sizeof(SList));if (phead == NULL){perror("malloc error");return NULL;}phead->data = -1;//因为是循环链表,所以初始化要遵循循环格式phead->next = phead;phead->prve = phead;return phead;
}
//创建链表节点
SList* ListBuyNode(SLDataType x)
{SList* retNode = (SList*)malloc(sizeof(SList));if (retNode == NULL){perror("malloc error");return NULL;}retNode->data = x;retNode->prve = retNode;retNode->next = retNode;return retNode;
}
//链表尾插
void SLPushBack(SList* phead, SLDataType x)
{assert(phead);SList* Node = ListBuyNode(x);Node->prve = phead->prve;Node->next = phead;phead->prve->next = Node;phead->prve = Node;
}
//链表数据显示
void SLPrint(SList* phead)
{assert(phead);SList* pcur = phead->next;while (pcur != phead)//哨兵位作为结束标识{printf("%d", pcur->data);if (pcur->next != phead)printf("->");pcur = pcur->next;}printf("\n");
}
//链表头插
void SLPustFront(SList* phead, SLDataType x)
{assert(phead);SList* Node = ListBuyNode(x);Node->next = phead->next;Node->prve = phead;phead->next->prve = Node;phead->next = Node;
}
//链表尾删
void SLPopBack(SList* phead)
{assert(phead);assert(phead->next != phead);SList* del = phead->prve;del->prve->next = phead;phead->prve = del->prve;free(del);del = NULL;
}
//链表头删
void SLPopFront(SList* phead)
{assert(phead);assert(phead->next != phead);SList* del = phead->next;del->next->prve = phead;phead->next = del->next;free(del);del = NULL;
}
//指定位置插入
void SLInsert(SList* pos, SLDataType x)
{assert(pos);SList* Node = ListBuyNode(x);Node->next = pos->next;Node->prve = pos;pos->next = Node;Node->next->prve = Node;
}
//查找节点
SList* SLfind(SList* phead, SLDataType x)
{assert(phead);SList* pcur = phead->next;while (pcur != phead){if (pcur->data == x){return pcur;}pcur = pcur->next;}return NULL;
}
//指定位置删除
void SLEarse(SList* pos)
{assert(pos);pos->prve->next = pos->next;pos->next->prve = pos->prve;free(pos);pos = NULL;
}
//链表销毁
void SLDestory(SList** pphead)
{assert(pphead && *pphead);SList* pcur = (*pphead)->next;while (pcur != *pphead){SList* next = pcur->next;free(pcur);pcur = next;}free(*pphead);*pphead = NULL;
}

test.c 函数的调用:

#include "List.h"void SLtest()
{SList* plist = NULL;plist = SLInit();//尾插SLPushBack(plist, 1);SLPushBack(plist, 2);SLPushBack(plist, 3);SLPushBack(plist, 4);SLPrint(plist);//打印:1->2->3->4//头插SLPustFront(plist, 5);SLPustFront(plist, 6);SLPustFront(plist, 7);SLPrint(plist);//打印:7->6->5->1->2->3->4//尾删SLPopBack(plist);SLPrint(plist);//打印:7->6->5->1->2->3//头删SLPopFront(plist);SLPrint(plist);//打印:6->5->1->2->3//指定位置插入SList* find = SLfind(plist, 5);SLInsert(find, 11);SLPrint(plist);//打印:6->5->11->1->2->3//指定位置删除find = SLfind(plist, 1);SLEarse(find);SLPrint(plist);//打印:6->5->11->2->3//链表销毁SLDestory(&plist);
}
int main()
{SLtest();return 0;
}

3、顺序表和双向链表的优缺点分析

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

数据结构第3篇笔记到这里也就结束了,我们下一篇笔记再见-

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

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

相关文章

勒索病毒--认知与防范

免责声明:本文仅做技术交流与学习... 目录 应急响应-勒索病毒 1、什么是勒索病毒&#xff1f; 勒索病毒是一种新型电脑病毒&#xff0c;主要以RDP爆破、邮件、程序木马、网页挂马的形式进行传播。该病毒性质恶劣、危害极大&#xff0c;一旦感染将给用户带来无法估量的损失。…

已解决 SyntaxError: invalid syntax,Python报错原因和解决方案。

「作者简介」&#xff1a;冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础著作 《网络安全自学教程》&#xff0c;适合基础薄弱的同学系统化的学习网络安全&#xff0c;用最短的时间掌握最核心的技术。 这篇文章带大家…

2065.最大化一张图中的路径价值

解题思路 枚举 枚举从0开始所有可能的路径&#xff0c;代码能力就是如何枚举&#xff0c;递归回溯 递归函数&#xff1a;当前节点&#xff0c;当前路径总时间&#xff0c;节点的价值之和。对相联通的节点进行递归搜索&#xff0c;如果回到节点0&#xff0c;则更新。 超过总时…

精灵图和base64的区别

精灵图&#xff1a;把多张小图整合到一张大图上&#xff0c;利用定位的一些属性把小图显示在页面上&#xff0c;这样访问页面的时候&#xff0c;可以减少请求次数&#xff0c;提高加载速度。 base64&#xff1a;这是一种传输8bit字节代码的编码方式&#xff0c;是一种用64个字符…

C++编程(七)继承

文章目录 一、继承&#xff08;一&#xff09;概念&#xff08;二&#xff09;语法格式&#xff08;三&#xff09;通过子类访问父类中的成员1. 类内2. 类外 &#xff08;四&#xff09;继承中的特殊成员函数1. 构造函数2. 析构函数3. 拷贝构造函数4. 拷贝赋值函数 二、多重继承…

怎样把热门抖音短视频下载保存到手机相册?

怎样把热门抖音短视频下载保存到手机相册? 1、在手机上打开抖音短视频APP&#xff1b; 2、打开后搜索或找到要下载保存的抖音短视频&#xff1b; 3、打开短视频后&#xff0c;点击右则的分享&#xff0c;并滑动找到保存到相册&#xff1b; 4、点击后等待完成下载&#xff0c;…

Python实现接糖果小游戏

介绍: 基于Pygame的糖果从屏幕顶部下落的游戏代码。这个游戏包括了一个可以左右移动的篮子来接住下落的糖果&#xff0c;接住糖果会增加得分。 代码: import pygame import random import os# 初始化pygame和设置屏幕大小 pygame.init() screen_width, screen_height 800, 6…

【LeetCode】反转字符串中的单词

目录 一、题目二、解法完整代码 一、题目 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意&#xff1…

读hugging face的daily paper随笔

hugging face’s daily paper 2024.06.29 OMG-LLaVA 像素级视觉理解、推理。 实现了image-level、object-level、pixel-level的推理和理解。 Step-DPO LLM长链推理的step-wise偏好优化&#xff0c;提高LLM的数学推理能力。 MUMU 引导多模态的图像生成&#xff0c;从多模…

海康视频播放,包含h5和web插件

自行下载 海康开放平台 demo 都写得很清楚&#xff0c;不多描述 1.视频web插件 vue2写法&#xff0c;公共vue文件写法&#xff0c;调用文件即可 开始时需要以下配置&#xff0c;不知道的找对接平台数据的人&#xff0c;必须要&#xff0c;否则播不了 getParameterData: {po…

万字总结随机森林原理、核心参数以及调优思路

万字总结随机森林原理、核心参数以及调优思路 在机器学习的世界里&#xff0c;随机森林&#xff08;Random Forest, RF&#xff09;以其强大的预测能力和对数据集的鲁棒性而备受青睐。作为一种集成学习方法&#xff0c;随机森林通过构建多个决策树并将它们的预测结果进行汇总&…

[Day 20] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

AI在醫療領域的創新應用 隨著科技的快速發展&#xff0c;人工智能&#xff08;AI&#xff09;在各行各業的應用越來越廣泛&#xff0c;醫療領域也不例外。AI技術在醫療中的應用不僅提高了診斷的準確性&#xff0c;還改善了病患的治療效果&#xff0c;優化了醫療資源的配置。本…

暴雨来袭,陈赫家变“水帘洞”网友:赫哥滴滴打船吗?

在魔都上海&#xff0c;一场突如其来的暴雨 不仅让街道变成了河流&#xff0c;还悄悄上演了一场现实版的“水帘洞”奇遇 而这场奇遇的主角&#xff0c;竟然是喜剧界的明星——陈赫&#xff01; 这天&#xff0c;乌云密布&#xff0c;电闪雷鸣 魔都的天空仿佛被捅了个窟窿 雨…

吴恩达《LangChain for LLM Application Development》课程笔记

目录 1. 前言 2. 课程笔记 2.1. 模型、提示和解析器 2.2. LLM记忆&#xff0c;上下文管理 2.3. 链式操作 2.4. 文档问答 2.4.1. stuff 方法 2.4.2. 其他方法 2.5. LLM应用评估 2.6. 代理 2.6.1. 预定义工具 2.6.2. 自定义工具 代码资源&#xff1a; 1. 前言 LangC…

文心一言 VS 讯飞星火 VS chatgpt (293)-- 算法导论21.4 2题

二、证明&#xff1a;每个结点的秩最多为 ⌊lgm⌋ 。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 在数据结构和算法中&#xff0c;当我们谈论“结点的秩”时&#xff0c;这通常与某些特定的数据结构&#xff08;如B树或B树&#xff09;相关&#xff0c;其中每…

SSH特性|组成|SSH是什么?

SSH&#xff0c;全称为Secure Shell&#xff0c;是由Internet Engineering Task Force (IETF)的网络工作小组制定的一种网络安全协议。它旨在为网络服务提供安全的远程登录和其他网络服务&#xff0c;如文件传输&#xff0c;端口转发等&#xff0c;以保护数据的机密性和完整性。…

代码随想录算法训练营第40天| 518. 零钱兑换 II、 377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)

518. 零钱兑换 II 题目链接&#xff1a;518. 零钱兑换 II 文档讲解&#xff1a;代码随想录 状态&#xff1a;不会 思路&#xff1a; 和494.目标和类似&#xff0c;这题属于组合问题&#xff0c;当我们有一个硬币coin时&#xff0c;对于每个金额j&#xff0c;通过添加这个硬币&a…

从零学习python打卡笔记 第一天

小学生都开始学python了&#xff0c;你还有什么资格不学&#xff1f; 打卡笔记的python版本是3.12.4 一、python能干什么工作&#xff1f; web全栈工程师、大数据分析工程师、爬虫工程师、人工智能工程师、游戏开发工程师、自动化测试工程师、搜索引擎工程师、自动化运维工程师…