数据结构与算法的代码实现(C++版)

数据结构与算法的代码实现(C++版)

  • 1. 线性表的顺序表示和实现
    • 1.1 线性表的初始化
    • 1.2 线性表的销毁
    • 1.3 线性表的清空
    • 1.4 线性表的长度
    • 1.5 判断线性表是否为空
    • 1.6 线性表的线性表取值
    • 1.7 线性表的顺序查找
    • 1.8 线性表的插入
    • 1.9 线性表的删除
    • 总结
  • 2. 线性表的链式表示和实现
    • 2.1 单链表的初始化(带头结点的单链表)
    • 2.2 判断单链表为空
    • 2.3 单链表的销毁
    • 2.4 单链表的清空
    • 2.5 单链表的表长
    • 2.6 单链表的取值
    • 2.7 单链表的按值查找
    • 2.8 单链表的插入
    • 2.9 单链表的删除第i个结点
    • 总结

1. 线性表的顺序表示和实现

1.1 线性表的初始化

// 线性表的定义
// 其实就是构造结构体:数组+长度
struct SqList
{ElemType* elem;  //顺序线性表的表头// 也可以这样定义,但是是数组静态分配,上述是动态的,因为可以使用指针指向数组首地址//ElemType elem[MAX_SIZE];  int length;      //顺序线性表的长度
};
// 线性表的初始化
bool InitList(SqList& L)
{L.elem = new ElemType[MAXSIZE];  // //在堆区开辟内存if (!L.elem){return false;}L.length = 0;  //设定空表长度为0return 1;
}

1.2 线性表的销毁

// 线性表的销毁
void DestroyList(SqList& L)
{if (L.elem){delete L.elem;}
}

1.3 线性表的清空

// 线性表的清空
void CLearList(SqList& L)
{L.length = 0;
}

1.4 线性表的长度

// 线性表的长度
int GetLength(SqList& L)
{return L.length;
}

1.5 判断线性表是否为空

// 判断线性表是否为空
bool IsEmpty(const SqList& L)
{// static_cast<bool>(L.length) 的作用是将 L.length 的值转换为布尔值 (bool)。return static_cast<bool>(L.length);
}

1.6 线性表的线性表取值

// 线性表取值
// 随机存取的时间复杂度是:O(1)
bool GetELem(const SqList &L, const size_t i, ElemType &e)
{if (i < 1 || i > MAXSIZE){cerr<<"out of range"<<endl;return false;}e = L.elem[i-1];return true;
}

1.7 线性表的顺序查找

// 线性表的查找
// 顺序查找的时间复杂度是:O(n)
int LocateList(const SqList& L, const ElemType& e)
{for (int i = 0; i < L.length; i++){if (L.elem[i] == e){return i + 1;  //查找成功,返回下标值}}return 0;  // 查找失败,返回0
}

在这里插入图片描述

1.8 线性表的插入

// 线性表的插入
// 顺序存储的插入的时间复杂度是:O(n)
bool InsertList(SqList& L, const ElemType& e, const int& i)
{if (i < 1 || i > L.length){return false;  // i值不合法}if (L.length == MAXSIZE){return false;  // 当前存储空间已满}// 将位于插入位置之后的元素依次向后挪动一位for (int j = L.length - 1; j >= i - 1; j--){L.elem[j + 1] = L.elem[j];}// 插入元素L.elem[i - 1] = e;// 线性表长度+1L.length++;return true;
}

在这里插入图片描述

1.9 线性表的删除

// 线性表的删除
// 顺序存储的删除的时间复杂度是:O(n)
bool EraseList(SqList& L, const int& i)
{if (i < 1 || i > L.length){return false;  // i值不合法}// 从要删除的i位置开始遍历// 也就是将位于删除位置之后的元素依次向前移一位for (int j = i; j < L.length; j++){L.elem[j - 1] = L.elem[j];}// 线性表长度-1L.length--;return true;
}

在这里插入图片描述

总结

(1)利用数据元素的存储位置表示线性表中相邻数据元素之间的前后关系,即线性表的逻辑结构与存储结构一致
(2)在访问线性表时,可以快速地计算出任何一个数据元素的存储地址。因此可以粗略地认为,访问每个元素所花时间相等
这种存取元素的方法被称为随机存取法
时间复杂度
1.查找、插入、删除算法的平均时间复杂度为O(n)
就是求次数,比如查找,就是在第几个位置需要的查找次数的累加和 / 元素个数。
比如插入,就是在第几个位置插入需要移动元素个数的累加和 / n种可能。
比如删除,就是在第几个位置删除需要移动元素个数的累加和 / n种可能。
空间复杂度
2.显然,顺序表操作算法的空间复杂度S(n)=O(1) (没有占用辅助空间)
优点
1.存储密度大(结点本身所占存储量 / 结点结构所占存储量,是1:1)
2.可以随机存取表中任一元素
缺点
1.在插入、删除某一元素时,需要移动大量元素
2.浪费存储空间
3.属于静态存储形式,数据元素的个数能自由扩充

2. 线性表的链式表示和实现

2.1 单链表的初始化(带头结点的单链表)

// 单向链表的定义
struct Lnode
{ElemType data;  //结点的数据域 Lnode* next;    //结点的指针域, 因为指针还是指向下一结点,结点类型就是Lnode
};
// typedef 都是常用来创建类型别名的工具。
// 将 Lnode * 这个指针类型定义为 LinkList,使得代码更简洁易读。
typedef Lnode* LinkList;  // 链表的初始化
bool InitList(LinkList& L)
{// LinkList& L = Lnode* L,L其实是Lnode类型的指针// 表示头指针L = new Lnode;  // 在堆区开辟一个头结点,结点的数据类型为Lnode//L->next = NULL;  // 空表,也就是说头结点的指针指向为空L->next = nullptr;  // // 使用 C++11 的 nullptr,类型安全return 1;
}

2.2 判断单链表为空

// 判断链表是否为空
bool IsEmpty(const LinkList& L)
{if (L->next){// 非空return false;}else{// 为空return true;}
}

2.3 单链表的销毁

在这里插入图片描述

// 单链表的销毁
void DestroyList(LinkList& L)
{LinkList p;while (L){// 就是定义1个指针p指向头结点,然后将头指针指向下一个结点,并删除当前p指向的结点p = L;L = L->next;delete p;}
}

2.4 单链表的清空

在这里插入图片描述

// 单链表的清空
void CLearList(LinkList& L)
{LinkList p, q;p = L->next;while (p)  // p非空,表示还没到表尾{q = p->next;delete p;p = q;}L->next = nullptr;  // 头结点指针域为空
}

2.5 单链表的表长

在这里插入图片描述

// 单链表的长度
int GetLength(LinkList& L)
{LinkList p;p = L->next;  // 将p指向首元结点 int i = 0;  // 计数while (p){// 遍历单链表,统计结点数i++;p = p->next;}return i;
}

2.6 单链表的取值

在这里插入图片描述
在这里插入图片描述

// 单链表的取值
bool GetElem(const LinkList& L, const int& i, const ElemType& e)
{LinkList p = L->next; int j = 1; // 计数器while (p && i > j){p = p->next;j++;}if (!p || j > i) return false; // 第i个元素不存在e = p->data;return true;
}

2.7 单链表的按值查找

在这里插入图片描述
在这里插入图片描述

// 单链表的按值查找,返回L中值为e的数据元素的地址
// 时间复杂度:0(n)
LinkList LocateElem(LinkList& L, ElemType& e)
{// 在线性表L中查找值为e的数据元素// 找到,则返回L中值为e的数据元素的地址,查找失败返回NULLLinkList p = L->next;while (p && p->data != e){p = p->next;}return p;
}// 单链表的按值查找,返回L中值为e的位置序号
int LocateElem(LinkList& L, ElemType& e)
{// 返回L中值为e的数据元素的位置序号,查找失败返回LinkList p = L->next;int j = 1;while (p && p->data != e){p = p->next;j++;}if (p){return j;}else{return 0;}
}

2.8 单链表的插入

在这里插入图片描述
在这里插入图片描述

// 单链表的插入
// 时间复杂度:0(1)
bool InsertList(LinkList& L, const int& i, const ElemType& e)
{LinkList p = L;int j = 0;while (p && j < i -1)  // 寻找第i - 1个结点, p指向i - 1结点{p = p->next;j++;}if (!p || j > i - 1){return 0;  // i大于表长+1或者小于1,插入位置非法}// 生成新结点s,将结点s的数据域置为eLinkList s = new Lnode;s->data = e;// 将结点s插入L中s->next = p->next;p->next = s;
}

2.9 单链表的删除第i个结点

在这里插入图片描述
在这里插入图片描述

// 单链表的删除
// 将单链表L中第i个数据元素删除
// 时间复杂度:0(1)
bool EraseList(LinkList& L, const int& i, const ElemType& e)
{LinkList p = L, q;int j = 0;while (p && j < i - 1)  // 寻找第 i 个结点的前驱{p = p->next;j++;}if (!(p->next) || j > i - 1){return 0;  // 删除位置不合理}q = p->next;  // 临时保存被删结点的地址以备释放p->next = q->next; // 改变删除结点前驱结点的指针域e = q->data;delete q;return true;
}

总结

在这里插入图片描述

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

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

相关文章

JavaScript ES6+ 新特性

JavaScript ES6 新特性 引言 随着前端技术的不断发展&#xff0c;JavaScript 语言也在不断演进。自 ES6&#xff08;ES2015&#xff09;发布以来&#xff0c;JavaScript 引入了许多新的特性和语法&#xff0c;极大地提升了开发者的编程体验和代码的可维护性。本篇文章将详细探…

真话有危险,测评需谨慎!一个家最大的内耗:谁都在抱怨,没人肯改变——早读(逆天打工人爬取热门微信文章解读)

现在都这么完了吗&#xff1f; 引言Python 代码第一篇 洞见 一个家最大的内耗&#xff1a;谁都在抱怨&#xff0c;没人肯改变第二篇 故事风云录结尾 引言 慢慢调整时间 一是现在有点忙 做那个传播声音的研究实验实在是有点没有头绪 没有头绪的事情你就不知道怎么安排时间 也就…

3144. 分割字符频率相等的最少子字符串(24.8.28)

题目 题目&#xff1a; 给你一个字符串 s &#xff0c;你需要将它分割成一个或者更多的平衡子字符串。 比方说&#xff0c;s "ababcc" 那么 ("abab","c","c") &#xff0c;("ab","abc","c") 和 (&quo…

数学建模比赛(国赛)水奖攻略

之前很多同学私聊问我&#xff0c;学校要求参加数模比赛&#xff0c;但是不擅长建模编程&#xff0c;但又不想浪费这个时间该怎么办呢&#xff0c;今天就来给大家讲一下大家都非常感兴趣的内容——数学建模水奖攻略。分享一下博主直接参加比赛时候的经验。 一、选题技巧 有一句…

HarmonyOs如何获取rawfile目录下的所有文件列表

最近在做一个功能&#xff0c;需要使用获取rawfile下目录的所有文件 参考连接为&#xff1a; zRawfile-模块-C API-Localization Kit&#xff08;本地化开发服务&#xff09;-应用框架 - 华为HarmonyOS开发者 (huawei.com) 需要使用到native实现&#xff0c;实现步骤&#…

2008-2020年 中国健康与养老追踪调查CHARLS数据合集

中国健康与养老追踪调查&#xff08;China Health and Retirement Longitudinal Study, CHARLS&#xff09;是一项由北京大学国家发展研究院主持的大型跨学科调查项目。该项目始于2011年&#xff0c;每两到三年对样本进行一次追踪调查&#xff0c;旨在收集代表中国45岁及以上中…

在CentOS 7上安装MongoDB的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 MongoDB 是一个免费、开源的面向文档的数据库。它被归类为 NoSQL 数据库&#xff0c;因为它不依赖于传统的基于表的关系数据库结构…

C++_CH13_面向对象编程

C_CH13_面向对象编程 1.1 类 类&#xff08;class&#xff09;是数据和操作的组合。 我们以游戏角色为例&#xff0c;创建一个类 #include<iostream>class player//player这个类是我们自定义的一个类型 {int x;int y;//二维坐标int speed;//速度int power;//力量};int…

重载与重写:Java中方法的多态性

重载与重写&#xff1a;Java中方法的多态性 引言 在Java编程语言中&#xff0c;多态性是一个核心概念&#xff0c;它允许我们以统一的方式处理不同类型的对象。Java提供了两种实现多态性的方法&#xff1a;重载&#xff08;Overloading&#xff09;和重写&#xff08;Overrid…

面试经典算法150题系列-反转字符串中的单词

反转字符串中的单词 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意&#xff1a;输入字符串 s中可能…

react 中的useState useEffect

下面的这些hook我们常用的一些 useState useEffect useCallback、useMemo、useRef 和 useContex 下一个文章中讲述&#xff08;useCallback、useMemo、useRef 和 useContex&#xff09; 下面我将讲解什么时候使用是最好的 首先我们需要明确的一点是&#xff0c;这些hook都…

转-600条最强linux命令

一、基本命令 uname -m 显示机器的处理器架构 uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 (SMBIOS / DMI) hdparm -i /dev/hda 罗列一个磁盘的架构特性 hdparm -tT /dev/sda 在磁盘上执行测试性读取操作系统信息 arch 显示机器的处理器架构 uname -…

关于告警,要想做好,从这些方面着手

各类监控系统都会产生告警事件&#xff0c;于是&#xff0c;就产生了 FlashDuty、PagerDuty、Opsgenie 这类产品&#xff0c;做告警事件的收敛降噪、排班认领升级等。如果你想增强自己公司的告警事件处理能力&#xff0c;参考&#xff08;chao xi&#xff09;这些产品的功能就可…

使用统计方法在AMD GPU上使用JAX Profiler可靠地比较大型生成AI模型中的算法性能

Using statistical methods to reliably compare algorithm performance in large generative AI models with JAX Profiler on AMD GPUs — ROCm Blogs 摘要 本文提供了一份详细的指南&#xff0c;介绍如何在JAX实现的生成AI模型中测量和比较各种算法的性能。利用JAX Profiler…

35岁程序员的4条出路!请提早布局!

小编准备入门了Python入门学习籽料80个Python爬虫实战入门实例 点击 领取&#xff08;无偿获得&#xff09; 20多岁&#xff0c;初入职场&#xff0c;满腔热血&#xff0c;对未来充满憧憬&#xff1b; 30多岁&#xff0c;家庭事业双重压力&#xff0c;开始迷茫&#xff0c;对…

阿里云发送短信功能(Java)

&#xff08;1&#xff09;注册用户&#xff0c;并且开通短信套餐 &#xff08;2&#xff09; 点击快速学习&#xff0c;然后绑定测试的手机号码。 选用专用测试签名&#xff08;自定义的话阿里可能会验证什么什么的比较麻烦&#xff09; 然后在选取调用API &#xff08;3&…

10、Flink 动态表之表到流的转换详解

表到流的转换 动态表可以像普通数据库表一样通过 INSERT、UPDATE 和 DELETE 来不断修改,它可能是一个只有一行、不断更新的表,也可能是一个 insert-only 的表,没有 UPDATE 和 DELETE 修改,或者介于两者之间的其他表。 在将动态表转换为流或将其写入外部系统时,需要对这些…

3秒AI写真出图,Stable Diffusion2024升级版+使用教程来了!(无需安装,解压即用)

要说今年摄影圈最大的新秀 那妥妥的就Stable Diffusion 比如下面的写真照片 你敢信这是SD绘画生成的&#xff1f; 就在刚刚它又全面升级了 新版无需安装&#xff0c;直接解压就能用 比之前推送的更加智能、快速和简单 另外还特意为大家准备了 Stable Diffusion 人工智能…

故障诊断 | 基于小波时频图与Swin Transformer的轴承故障诊断方法(PyTorch)

文章目录 文章概述程序设计参考资料文章概述 基于小波时频图与Swin Transformer的轴承故障诊断方法 针对用传统的故障诊断方法难以对非线性非平稳的柴油机故障信号进行准确高效诊断的问题, 提出基于小波时频图与Swin Transformer的故障诊断方法。该方法可以有效结合小波时频分…

Git实战精粹

一、快速入门 1. 什么是Git Git是一个分布式的版本控制软件。 软件&#xff0c;类似于QQ、office、dota等安装到电脑上才能使用的工具版本控制&#xff0c;类似于毕业论文、写文案、视频剪辑等&#xff0c;需要反复修改和保留原历史数据分布式 文件夹拷贝本地版本控制集中式…