C++基础-介绍·数据结构·排序·算法

news/2024/11/7 15:10:20/

C++基础-介绍·数据结构·排序·算法

  • 特点
  • 使用方向
  • RPC
  • 数据结构
    • 栈 Stack
    • 堆 Heap
    • 队列 List
    • 数组 Array
    • 链表 LinkTable
    • 树 Tree
      • (普通)二叉树
      • 二叉查找树 Tree Search
      • 平衡二叉树
      • 红黑树
    • 冒泡排序
    • 选择排序
    • Insertsort 插入排序
    • Quicksort 快速排序
    • Binarysearch 二分查找/折半查找
    • Blocksearch 分块查找
    • Treesearch 树查找
    • 哈希算法
    • 龟兔赛跑算法
    • 递归算法

特点

C++是一门风格严谨又不失自由的开发语言,提供了完整的内存管理、支持函数式编程和面向对象编程,支持模板、多继承、多实现、重载、重写等多态特性。
优势在于目前90%的操作系统、数据库、应用基础架构、硬件嵌入式等都是使用C/C++制作的,而C++是对C的标准扩展,掌握C++的过程中也能比较好地掌握C本身。
缺点也比较鲜明,由于原始指针需要操作内存,并且有各种引用、双重引用、移动语义非常容易让新手望而生畏,即使后来有智能指针后也由于带有额外的资源消耗而被诟病。
最大的缺点在于对中国国内流行的互联网环境支持性不好,在大量Java、Go、Python流行作为服务后端开发语言时,C++却在这方面并没有易于使用的框架或者基础辅助快速构建后端服务。

使用方向

  • 底层、基础架构、数据库开发,如RPC协议、Redis、Nginx、RocketMQ中间件
  • 音视频
  • 游戏引擎
  • 网络安全、sdn
  • 结合mfc/qt做软件
  • linux嵌入式、芯片
  • 虚拟化、操作系统

RPC

RPC即远程调用(Remote-Procedure-Call),指的是在分布式应用程序中,由于不同的服务程序处于不同的进程甚至不同服务器中,需要通过各种协议进行调用,例如网站之间可以通过HTTP协议调用彼此的接口,或者通过TCP/UDP协议完成即时传输,而使用RPC是程序之间高效传输的最佳选择。
其中有谷歌通用框架gRPC SDK,包含了在不同开发语言中的RPC实现,还有protobuf(Google Protocol Buffer)实现了一种自定义数据格式用于消息传输,相比xml、json体积更小,解析速度更快。

数据结构

栈 Stack

连续存储空间,出入口为同一个,只能先进后出,后进先出。
栈的分配与删除处理都很快,相当于移动指针,几乎只是一条CPU指令就能完成。
栈会所在作用域结束时会自动删除来释放内存,例如在方法里创建栈变量会在方法结束后删除,甚至可以在方法内部添加花括号来加速栈变量删除。

堆 Heap

栈与堆都是存放在内存里,只是在不同地方,也造成了分配方式不同。
程序专门开辟使用的内存存储空间,采用类似树结构储存,如果开发语言没有设定垃圾收集机制的话,需要程序员手动操作释放或者等程序结束才会回收。
堆的分配和删除很慢,程序需要维护、查找内存空闲列表也有消耗,一般通过new和delete关键字使用,两者都需要好几条指令完成,因此也造成大量资源消耗。
程序需要维护、查找内存空闲列表也有消耗。
new相当于自动调用malloc(memory allocate)分配堆内存。

队列 List

出口和入口各独立一个,先进先出,后进后出。

数组 Array

连续存储空间,有序,带有索引,可重复。可以高效率根据索引查找,但增删时涉及移动其他项导致效率慢。

链表 LinkTable

节点存储有数据和指向下一个节点的地址,多个节点串联起来,因为这种特性让增删节点比数组高效,但查询需要从头到尾遍历导致效率比数组低。
双向链表:让表的链接从头到尾,从尾到头两个方向都有地址指向,让头尾都可进行增删改,因此对头尾元素的处理更方便。
大部分Collection和List都是用数组混合链表,可以比较好地确保存入顺序和高效的增删改查。

树 Tree

从一个根节点出发,每个节点带有若干个子节点,并且这些子节点同样可以带有自己若干个孙子节点,这样就叫树结构。其中主要是二叉树。
大部分Map,Set底层就是链表混合树结构,具体看是否需求有序和排序等。

(普通)二叉树

每个节点上所包含的子节点不超过2个即称为二叉树,没有按照一定规律存储数据的二叉树没有任何搜索查找优化,不值得使用。

二叉查找树 Tree Search

将普通二叉树的数据按照一定规律存储即称为二叉查找树,一般规律是所有父节点都比左子节点大而比右节点小。
这样搜索时,可以通过从父节点开始比对,从而快速决定在左子树还是右子树继续查找,类似二分查找。

平衡二叉树

所有父节点的左右子节点高度差不超过1的二叉查找树就称为平衡二叉树。
在增删数据时,为了保持平衡,二叉树需要进行旋转操作,常见有:

  • 左左,在根节点的左子节点中的左子节点添加数据时,需要进行一次右旋达成平衡。
  • 左右,在根节点的左子节点中的右子节点添加数据时,可能需要进行一次局部左旋后再进行整体右旋。
  • 右右,在根节点的右子节点中的右子节点添加数据时,需要进行一次左旋达成平衡。
  • 右左,在根节点的右子节点中的左子节点添加数据时,可能需要进行一次局部右旋后再进行整体左旋。

红黑树

含有颜色标记的非平衡二叉树,规则:

  • 节点都为红色或者黑色
  • 根节点和Nil叶节点必须为黑色
  • 若是没有子节点或者没有父节点,则将该链接点标记为Nil叶节点
  • 红色节点之间不能互相连接
  • 从同个节点到后代所有Nil叶节点的路径上,每条路径所包含的黑色节点数量都是相同的(通过变红处理)

插入数据时一般默认为红色,根据情况才需要处理为黑色。

冒泡排序

通过不断对比临近索引的值,经过多次循环完成排序。

int arr[7] = {5,1,9,11,3,2,7};
for (int i = 0; i < 7; i++) {}

选择排序

通过先将指定索引的值与所有其他数进行对比交换,之后经过多次循环完成所有指定索引的值的对比。

Insertsort 插入排序

先找到前面有序的部分,和后面无序的分开,之后通过类似冒泡排序的方式完成将后面无序的部分插入到前面有序的部分。

Quicksort 快速排序

先找到中间值,通过顺序和逆序遍历将值根据中间值交换位置。

Binarysearch 二分查找/折半查找

(前提:数据必须是有序的)先拿到中间索引的值进行对比,得到想要的值在左半边还是右半边,之后对所在的半边再次执行拿到中间索引的值进行对比后分半的操作,重复循环直到找到目标。
此方法适合数据量巨大但已经排序好,且分布比较规律的。
如果只是分布不规律可以采用黄金分割或者根据情况判断采用三分之二而非二分之一。

int arr[15] = {1,2,3,6,8,11,19,22,29,48,51,54,62,88,110};

Blocksearch 分块查找

(前提:先完成数据分块,块内可以无序,但块之间必须有序。)根据需要在对应的数据块再进行查找,减少循环所需次数。

Treesearch 树查找

树一般是二叉树或红黑树等已经有序的树结构,可以根据树特性借助递归轻松完成查找。

哈希算法

通过使用哈希表记录的方式,尽可能减少循环次数。

龟兔赛跑算法

通过使用索引先求链表的方式,尽可能减少带有规律的数组的时间复杂度。

/*** 判圈算法找到数组里的重复项(判圈算法又称龟兔赛跑算法)* @param {Array<number>} nums 需要找出重复项的数组*/
function findDuplicate(nums) {let tortoise = 0, hare = 0;while (tortoise !== hare && hare !== undefined) {tortoise = nums[tortoise];hare = nums[hare];if (hare !== undefined) {hare = nums[hare];}}if (hare === undefined) return hare;tortoise = 0;while (tortoise !== hare) {tortoise = nums[tortoise];hare = nums[hare];}return hare;
}

递归算法

通过拆分出重复的规律作为函数并自己调用自己大幅减少内存占用。


http://www.ppmy.cn/news/64139.html

相关文章

开源智慧家居

与家居行业、服务行业等伙伴协同合作&#xff0c;努力创造社会价值&#xff0c;提升行业整体服务 水平&#xff0c;树立家居服务业统一售后标准&#xff0c;构建品质、高效、有温度的居家生活服务新生态。 为企业商家和个人客户提供家居配送、搬运、安装、维修、保养等服务。 …

《时间从来不语,却回答了所有问题》笔记三

目录 感悟 经典摘录 假若我再上一次大学 不完满才是人生 走运与倒霉 毁誉 我的座右铭 二月兰 观天池 火车上观日出 感悟 人这个万物之灵却偏偏有了感情&#xff0c;有了感情就有了悲欢。自古及今&#xff0c;海内海外&#xff0c;一个百分之百完满的人生是没有的&…

【开发经验】spring事件监听机制关心的同步、异步、事务问题

文章目录 spring发布订阅示例同步核心源码分析如何配置异步事务问题 观察者模式又称为发布订阅模式&#xff0c;定义为&#xff1a;对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖它的对象都得到通知并被自动更新。 如下图所示&…

进程的暂停与继续

暂停一个进程 kill -STOP 1234或者 kill -TSTP 1234 // 通常 CtrlZ 发出该信号继续一个进程 kill -CONT 1234&、CtrlZ、jobs、fg、bg & 最经常被用到&#xff0c;这个用在一个命令的最后&#xff0c;可以把这个命令放到后台执行。 CtrlZ 可以将一个正在前台执行的…

HTB靶机08-Nineveh-WP

008-nineveh 靶机IP&#xff1a; 10.10.10.43 scan Nmap 扫描 ┌──(xavier㉿kali)-[~] └─$ sudo nmap -sSV -T4 10.10.10.43 -p- Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-07 17:40 CST Nmap scan report for nineveh.htb (10.10.10.43) Host is up (0.34s …

【刷题】141. 环形链表

141. 环形链表 一、题目描述二、示例三、实现思考总结 141. 环形链表 一、题目描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环…

EKMA曲线绘制、MCM箱模型应用与O3形成途径、生成潜势、敏感性分析

目录 EKMA曲线及大气O3来源解析 MCM箱模型实践技术应用与O3形成途径、生成潜势、敏感性分析 一、 大气中O3形成知识基础、MCM和Atchem2原理及Linux系统安装 二、 MCM建模、数据输入、模型运行及结果输出 【讲解案例操作】 三、 O3形成途径、生成潜势及其敏感性分析 【讲解…

vue diff算法与虚拟dom知识整理(5) 手写一个自己的h函数

本文的意义在于教会大家如何手写一个h函数 上文中 我们简单理解了一下h函数 他的作用是构建一个虚拟的dom节点 掌握这个函数还是很有必要的 首先 你想要写出来 还是得去看原版的ts代码 这边 我们没必要把太多注意力放在TS上 所以 我们这边是看ts代码 然后 仿写js代码 我们在…