并查集
目的1、 高效的解决点和点之间的连接问题,实例中就是网络中节点间的连接状态,这里的网络并不单单指代计算机网络,同时也指代现实中的关系网络.
2、 数学中的集合类实现,查询和并集合的操作.
连接问题和路径问题前者只需要进行判断,后者有着更广阔的应用空间吗,无论是两者之间的最短路径还是具体的路径情况.
并查集对于一组数据,支持两个动作
union(p,q) 合并两个集合
isConnected(p,q) 两个元素是否同属于一个集合
笔记内容
并查集的Rank[i]指的是根节点为i的树的高度.之所以不用height来形象的表示,是因为后面在路径压缩操作中,会将改变树的高度,这时候Rank值并不需要更新.是因为本身树高度的比较就是相对而言的,这时候Rank更多的意思是权重的意思.
代码实现基础版本# include <iostream>
class UF{
public:
UF(){}
virtual bool isConnected(int p,int q)=0;
virtual void unionElements(int p,int q)=0 ...
数据库开发学习 (2) 结构设计
业务数据库设计流程需求分析分析—>概要设计—>详细设计
瀑布模型和螺旋模型
瀑布模型: 只有往下迭代开发,没有回溯.多适合用于业务需求十分明确可以一次性完成开发
螺旋模型: 有回溯,多次迭代开发.每次开发仅完成一部分的内容,与瀑布模型相反,用敏捷开发快速迭代出一版,适用于业务需求并不明确.
宽表模式将属性全部列在一个表中
缺点
数据冗余,相同数据出现多次
维护成本高
更新异常
插入异常: 部分数据由于缺失主键信息而不得显示
删除异常: 删除某一数据时不得不删除另一数据
适用场景配合列存储的数据报表应用
逻辑设计: 数据库设计范式
第一范式: 表中的所有字段都是不可再分的
第二范式: 表中必须存在业务主键(能够唯一标识出每一行业务数据的列或者列的组合),并且非主键依赖于全部业务主键,意味着列非主键不能只依赖于组合业务主键中的某一个主属性
第三范式: 表中的非主键列之间不能相互依赖.(传递依赖),第三范式的目的就是为了让非主键列的字段只完全依赖于主键列,与其他列无关.
ER图:实体关系图,
属性语法
复合属性是多个属性的组合
多值属性是某个属性可以有多个不同的取值
派生属 ...
数据库开发学习 (1) 数据库概述
SQL VS NOSQLSQL主要指的是关系型数据库,主要代表是MySql等
NOSQL全部指的是Not only SQL,意味着不仅仅使用数据库来存储数据,主要代表是MongoDB
非关系数据库的特点
存储结构灵活,没有固定的结构
在不考虑数据压缩的条件下,占内存大
对事物的支持比较弱,但对数据的并发处理性能高
大多不适用SQL语言进行操作
使用场景
数据结构不固定的场景
对事务要求不高,但读写并发比较大的场景
对数据的处理比较简单的场景
关系数据库选型原则
数据库使用的广泛性
数据库的可扩展性
数据库的安全性和稳定性
数据库所支持的系统
数据库的使用成本(不仅仅是数据库本身的也有开发人员的)
MySQLs数据库的可扩展性
支持基于二进制日志的逻辑赋值
存在多种第三方数据库中间层,支持读写分离及分库分表
MySQL的安全性和稳定性
MySQL主从赋值集群可达到99%的可用性
配合主从赋值高可用架构可以达到99.99%的可用性
支持对存储在MySql的数据进行分级安全控制
STL- 算法(3) 常用算术生成算法、集合算法
算术生成算法accumulate算法计算容器元素累计总和
# include <numeric>
# include <algorithm>
T accumulate(iterator beg,iterator end,value)
@param beg 开始
@param end 结束
@param value 累加器
@return 其实累加值
fill 算法向容器中添加元素需要提前resize!!!
file(iterator beg,iterator end,value)
@param beg
@param end
@value 填充值
常用集合算法使用前记得给目标容器resize()!!!!
set_intersection算法interator set_intersection(interator beg1,interator end1,interator beg2,interator end2,interator target)
交集
@param beg1
@param end1
@param beg2
@param en ...
STL- 算法(2) 常用排序、替换算法
常用排序算法merge 算法容器元素合并,并存储到另一个容器中,这两个容器必须也是有序的目标容器必须resize()!!
merge(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator target_beg)
@param beg1 开始迭代器1
@param end1 结束迭代器1
@param beg2 开始迭代器2
@param end2 结束迭代器2
@param target 目标容器起始迭代器
sort 算法这个算法不知道干嘛的回去背英语吧
sort(iterator beg,iterator end)
sort(iterator beg,iterator end,_callback)
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 回调函数或者谓词(返回类型bool的函数对象)
random_shuffle 洗牌算法就是重新给数组随机排序
如果没有使用srand((unsigned int)time(NULL)),每一次运行结束 ...
STL- 算法(1) 概述 常用遍历、查找算法
算法概述算法主要是由头文件 组成
是所有STL头文件中最大的一个,其中常用的功能涉及到比较、交换、查找、遍历、复制、修改、反转、排序、合并等。
体积很小,只包括在几个序列容器上进行的简单运算的模板函数
定义了一些模板类,用以声明函数对象
仿函数、算法、适配器三者关系算法常常会和仿函数和适配器一起使用,仿函数用来扩展算法的功能,用一个重载()运算符来修改算法最关键处的功能
适配器则用来适配算法和仿函数的。
例如find_if中第三个参数在内部调用的时候只会传递给仿函数1个参数值,但是我们需要使用的仿函数有两个参数,这时候就需要用适配器来适配仿函数。
算法操作自定义数据成员容器中的成员为自定义数据类型的时候,需要在类内部对算法的功能模板行为进行重载。例如find算法中的模板行为为==,如果不使用find_if,就需要在类内部对==进行重载
常用的遍历算法_callback for_each(iterator begin,iterator end,_callback)
@param begin 容器开始迭代器
@param end 容器结束迭代器
@param _callback 回调 ...
LeetCode刷题(致敬跨年)单词拆分
题目描述
代码class Solution {public: bool wordBreak(string s, vector& wordDict) { if(s.empty()||wordDict.empty()) return false; int n=s.size(); vector dp(n+1,false); //表示到第n个字符为止 s是否能被字典拆分 dp[0]=true; for(int i=0;i<=n;i++) { for(auto word:wordDict) { int ws = word.size(); if(i - ws >= 0) { if (!s.compare(i-ws, ws, word)&&dp[i-ws]) { d ...
STL -函数适配器
适配器一种用来修饰容器或者仿函数或迭代器接口的东西
函数适配器使用步骤
继承binary_function<参数1,参数2,…,返回值>
加上const修饰operator
bind1st/bind2nd 绑定数据
bind1st 和bind2nd区别对于绑定的数据而言,bind2nd按照顺序绑定,bind1st逆序绑定
代码/*************************************************************************
> File Name: main.cpp
> Author:
> Mail:
> Created Time: 2019年12月31日 星期二 17时28分07秒
************************************************************************/
# include<iostream>
# include <string>
# include <vector> ...
STL -函数对象
函数对象重载函数调用操作符的类,其对象常称为函数对象,即他们是行为类似函数的对象,也叫仿函数,其实就是重载”()”操作符,使得类对象可以像函数一样调用。
Note
函数对象是一个类,不是一个函数
函数对象(仿函数)重载了”()” 操作符使得它可以像函数一样调用分类:假定某个类有一个重载的operator(),而且重载的operator()要求获取一个参数,我们就将这个类称为”一元仿函数”(unary functior),相反,如果重载的operator()要求获取两个参数,就将这个类称为”二元仿函数”(binary functor)
作用STL提供的算法往往都有两个版本,其中一个版本表现出最常用的某种运算,另一个版本则是允许用户通过template参数的形式来指定所要采取的策略。
代码例子/*************************************************************************
> File Name: main.cpp
> Author: 仿函数的使用方法
> Mail:
> Created ...
优先队列(堆) 最大堆和最小堆的实现
优先队列实现的实例:Heap(Binary,Binomial,Fibonacci) 堆
Binary Search Tree 二叉搜索树
小顶堆Mini Heap:优先级越小排在越前面,最小元素永远在堆顶,父亲节点永远比孩子节点的值小。
大顶堆和小顶堆相反
维基百科: https://en.wikipedia.org/wiki/Heap_(data_structure)
堆堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构,所以堆也叫做二叉堆。
二叉堆满足二个特性
1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。
最大堆和最小堆是堆数据结构的重点。堆排序中使用特别的多。
堆的存储一般是用一个数组实现的,当然也可以用链式存储,但是特别麻烦。
如下我们给出一个数组:
int* Arry={10,16,18,12,11,13,15,17,14,19 ...
STL -容器 <map> 相关API及原理
Map容器概念Map的特性是,所有元素都会根据元素的键值自动排序。Map所有的元素都是pair,同时拥有实值和键值,pair的第一元素被视为键值,第二元素被视为实值,map不允许两个元素具有相同的键值
我们可以通过map的迭代器改变map的键值吗?答案是不行的,因为map的键值关系到map元素的排列规则,任意改变map键值将会严重破坏map组织,如果想要改变元素的实值,那么是可以的
map和list拥有相同的某些性质,当对它的容器元素进行新增操作或者删除操作时,操作之前的所有迭代器,在操作完成之后依然有效,当然被删除的那个元素的迭代器必然是个例外
multimap和map操作类似,唯一区别是multimap键值可以重复。
map和multimap都是以红黑树为底层实现机制
API构造函数map<T1,T2> 默认构造
map(const map &mp) //拷贝构造
插入数据操作(返回值为pair<iterator,bool>)map<int,string> mapStu;
insert(pair<int,string>( ...
STL -容器 <set> 相关API及原理
Set容器的基本概念 set的特性是:所有的元素都会根据元素的键值自动被排序(对于int来说默认从小到大)。Set的元素不像map那样可以同时拥有实值和键值,set的元素即是键值又是实值。Set不允许两个元素有相同的键值
Set容器不能通过迭代器改变里面的值,因为set元素值就是其键值,关系到set元素的排序规则。如果任意改变set元素值,会严重破坏set组织,换句话说,set的iterator是一种const_iterator
set拥有和list某些相同的性质,当对容器中的元素进行插入操作或者删除操作的时候,操作之前所有的迭代器,在操作完成之后依然有效,被删除的那个元素的迭代器必然是一个例外。
multiset容器基本概念multiset特性及用法和set完全相同,唯一区别是允许键值重复,底层是用红黑树实现的。
API函数构造函数set<T> st //默认构造函数
multiset<T> mst
set(const set &st)
赋值操作set &operator =(const set &set);
swa ...