算法|十大排序算法与C++实现
十个经典的排序算法咱们评判一个算法的指标呢,常常有以下这几种
平均时间复杂度
时间复杂度,用通俗的话来说,假设有n个数据元素。一个操作(分原子操作)的时间*n
空间复杂度
空间复杂度,用通俗的话来讲,还是n个数据元素,运行算法时使用的n个存储空间。
排序方式
外部排序或是内部排序,外部就是需要使用到除要排序的数据存储外的还要使用的临时存储空间。
而内部,就是直接在数据存储的内存进行操作。
最好情况
顾名思义,时间复杂度的
最坏情况·1
顾名思义,时间复杂度的
冒泡从头或者从尾部开始,比较相邻的两q个元素,比大小规则,满足就交换。
做完一轮,最后或者开头的元素会是最大/最小值,循环-1,继续一轮比较。如此反复。
代码示范123456789void BubbleSort(vector<int>& arr, int size){ for (int i = 1; i < size; i++) { for (int j = 0; j < size - i; j++) { ...
MySQL与C++的环境开发|原生API
MySql基本基本概念关系数据库:表组成的数据库
Nosql数据库: 非关系数据库,并非由表构成,多是Key-value数据库,文件数据库,图等。
RDBMS 即关系数据库管理系统(Relational Database Management System)的特点:
1.数据以表格的形式出现
2.每行为各种记录名称
3.每列为记录名称所对应的数据域
4.许多的行和列组成一张表单
5.若干的表单组成database
数据库:就是数据表的集合
数据表:表是数据的矩阵,在一个数据库的表看起来像一个简单的电子表格。
表还有功能,视图,和过程。本文着重数据表的理解
列:一列数据元素,包含了相同类型的数据
行:一行元组或记录,是一组相关的数据
冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性(可以理解为多余的重复数据?不按单条规则的存放的,单条数据废了,还能通过冗余数据推出出现错误的数据信息)
主键:主键是唯一的,一个数据表中只能包含一个主键,通过主键来查询数据(唯一性数据,比如说唯一的编号数据)
索引: 利用索引快速访问数据表中的特定信息。索引是对数据表中一列或多列的值进行排序的一种 ...
C++注解|智能指针与原生指针
C++ 注解智能指针C++11,再管理动态分配内存上,引入的智能指针。哥们理解为,是原生指针raw point 的高级封装。
C++98 就提供了auto_ptr,但是,到了C++11后,不再建议使用,摒弃了auto_ptr,而是提供了unique_ptr , share_ptr与weak_ptr等
动态内存分配,能够有效的避免内存泄露的问题
多线程,多进程的动态分配内存中,常常可能因为某些原因,在释放内存,delete指针指向的内存之前,崩溃,异常捕获,造成内存泄露,悬挂指针问题
(当然还有可能忘记delete,这个就是程序员的问题了)
智能指针,将无需记住稍后释放这些new的内存,在智能指针过期时,这些内存将自动释放,你可以不用再担心释放问题(%90)
智能指针是具有线程安全的,shared指针中有个引用计数,并且引用计数的增加是原子操作。
需要注意的是,raw原生指针,与智能指针最好不要混用。
错误示例
1234567using namespace std;//原生指针double * raw_ptr = new double (3.14);//将原生指针指向赋予给了一个唯一指针 ...
C++注解|右值引用与移动语义
C++注解右值引用与移动语义C++11提供的新特性,相当有用,节省了很多开销,生了很多事。(ps:越来越感觉C++ 11的很多新特性有意在淡化raw指针的影响,有点java)
首先来大概了解一下什么事右值
右值右值,通常人们说放在等号 右边的值就是右值。
但是这只片面的,并不全面。
我们来看看传统的左值引用
1234567// 传统的左值引用int a = 10;int b = 20;int c = a + b;int& la = a;int& lb = b;int& lc = c;
a 就是左值,一个符号,有地址(在栈上),而10 本身就是一个右值。没有办法&取地址,一个常量。
a+b 实际上也是一个常量公式,也没办法取地址,也是只能放右边。
具体详细可以看cppreference对值类别的分类。
而我们使用的右值引用后
1234567int&& ra = 10;int&& rc = a + b; // 右值引用 cout << ra << char(10); cout << ...
C++注解|隐式声明的那些函数。
C++注解构造函数相关问题引出在使用自己定义的类实现某些操作时,可能会出现这样的报错。
error C2280: attempting to reference a deleted function
表示 被引用的函数已被删除的报错
并且表明该函数为拷贝赋值函数。可你发现,你根本就没有定义这个么函数,引用,和被删除的前提就是它之前存在过?那么我们问题就来了。
拷贝赋值函数:Tile &Tile::operator =(const Tile &)
注: Tile 不是模板。
探讨我们将问题定位在这个拷贝赋值函数上,探讨关于拷贝复制函数是如何出现的
我们都知道,(假设 自定义的名字为Tile)
C++的构造函数有:
默认构造函数 (无参)
析构函数 (无参)
拷贝构造函数
(const Tile &)return Tile&
拷贝赋值函数
operator= (const Tile &) return Tile&
operator= ( Tile &) return Tile&
移动构造函数
( Til ...
C++注解|程序的编译链接
C++注解程序的编译链接原理我们需要理解分析编译的过程理解打好坚实的C++基础,需要理解.o文件的格式组成,可执行文件的组成格式又是什么样子,理解符号表的输出符号,符号何时分配虚拟地址。这些能够帮助我们在出现问题时, 能够深入理解并快速找到问题
以下结合示例演示大概原理
工程结构为
12345.├── sum01.cpp└── test01.cpp0 directories, 2 files
sum01:
1234int gdata = 10;int sum(int a, int b){ return a + b;}
test01:
123456789extern int gdata;int sum(int, int);int data = 20;int main() { int a = gdata; int b = data; int ret = sum(a, b); return 0;}
编译进行编译过程大局分为三个阶段
所有的源文件都是单独编译的
预编译
编译
汇编
这三个步骤最终得到
二进制的可重定位的目标文件
预编译 ...
C++注解|类中的浅拷贝与深拷贝
类与深拷贝与浅拷贝测试测试构建类中的成员变量该类的指针,所出现的问题,与解决过程。
编译器 GCC lastest x64
系统 Linux Ubuntu22LTS
错误示例一12345678910111213141516171819202122232425class A{ int a; A* test; public: A(){ a = 0; test = new A(); }; A(int num) { a = num; this->test = new A(); }; ~A(){ if(test != nullptr) delete test; };};int main(){ A b(10); A a = b; return 0;}
在执行简单的拷贝时,我们使用编译器默认提供的拷贝构造函数。
编译的时候,确实没问题啊,但是一运行就开始报错了。返回一个 ...
linux基础08 | Socket简单的概念
SocketSocket的简单概念sock的本质,可以理解为高级管道?,也是伪文件。
有两端,有两个,成对的,是封装好的。
也可以理解为实际上一个文件描述符指向两个管道文件的缓冲区,一个读一个写。文件描述符服务端一个,客户端一个,然后完成全双工通信
网络字节序大端:低地址存高位,高地址存低位
小端:低地址存地位,高地址存高位
在计算机中一般数据结构存储都是小端存储法
网络字节流则是大端法存储。(历史遗留问题)
所以呢我们使用库函数做网络字节序和字节序进行转换
htonl
htons
ntohl
ntohs
n是net网络
h是host主机
l是长整32位数,ipv4用
s是短整16位数,port用
ip地址转换函数前置函数
都支持ipv4 ipv6
inet_ntop
ip转二进制
inet_pton
二进制转ip
sockaddr的数据结构原始的已经废弃了:struct sockaddr,毕竟一开始只是为了ipv4的,没想着拓展,用着用着不好用,换了其他新的。如此就会出现历史遗留问题比如说使用如下函数:bind
accept
connect
传值的类型需要进行强转
现在是stru ...