- 博客(104)
- 收藏
- 关注
原创 算法 等价类、并查集与图
等价关系与等价类等价集的初始状态,其数值都是-1,根据等价关系对齐数值进行修改假如0 = 4,于是将 4结点的数值加至 0 结点,并将0作为4结点的新数值 ,那么此时0结点就是3结点的根并查集的建立class UFSets{ int* parent; int size;public: UFSets(int sz) :size(sz) { parent = new int[size]; for (int i = 0; i < size; ++i) { par
2022-05-13 13:14:57
526
原创 算法 B+树 B*树
B+ 树B+ 树的概念B+ 树的定义B+ 树的插入B+ 树的概念B+ 树可以看作是B- 树的一种变形,再实现文件索引结构方面比B- 树使用得更普遍一颗 m 阶 B+ 树可以定义如下:树中每个非叶结点最多有m棵子树根节点(非叶结点)至少有 2 颗子树,除了根结点外,其它的非叶结点至少有[m/2]棵子树,有 n 棵子树的非叶结点有 n-1 个关键码所有的叶节点都处于同一层次上,包含了全部关键码及指向相应数据对象存放地址的指针,且叶结点本身按关键码从小到大顺序链接每个叶结点中的子树棵树 n 可
2022-05-11 17:52:24
560
原创 算法 B树
B树B- 树的概念B- 树的定义B- 树的插入B- 树遍历B- 树的删除B- 树的概念B树就是B-Tree,B-Tree的定义:根节点子女数为[2,m];除根节点和叶结点以外的所有分支结点至少有[ [m/2] , m]个子女;所有的叶结点都位于同一层;m 阶 B-Tree 的节点结构如下:n, S0, (K1,S1), (K2,S2), … ,(Kn,Sn)其中 Si 是指向子树的指针,0 <= i <= n < m;Ki是关键码,1 <= i <= n&l
2022-05-10 21:46:06
536
原创 算法 红黑树
红黑树红黑树概述红黑树性质红黑树的插入红黑树概述红黑树(Red Black Tree)是一种自平衡二叉查找树,是在计算机科学的中用到的一种数据结构,典型的用途是实现关联数组,红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能它虽然是复杂到,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的:它可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目红黑树性质红黑树是每个结点都带有颜色属性的二叉查找树,颜色是红色或黑色,
2022-05-10 15:58:38
854
原创 算法 T树(键树)
T树T树T树的定义T树的插入T树键树又称数字查找树(Digital Search Trees),它是一颗度>=2的树,树种的每个结点中不是包含一个或几个关键字,而是只含有组成关键字的符号,例如,若关键字是数值,则结点中只包含一个数位;若关键字是单词,则结点中只包含一个字母字符,这种树会给某种类型关键字的表的查找带来方便T树的定义const int MaxKeySize = 25;const int LETLEN = 27;typedef enum { BRCH = 0, ELEM = 1
2022-05-10 15:57:25
758
原创 算法 二叉树 AVL树
AVL树AVL树的定义结点的平衡因子 balanceAVL树的定义一颗AVL树或者是空树,或者是具有下列性质的二叉搜索树:它的左子树和右子树都是AVL树,且左子树和右子树的高度只差绝对值不超过 1结点的平衡因子 balance每个结点附加一个数字,给出该结点右子树的高度减去左子树的高度所得的高度差,这个数字即为结点的平衡因子balance根据AVL 树的定义,任一结点的平衡因子只能取 -1、0 和 1如果一个结点的平衡因子的绝对值大于1,则这颗二叉搜索树就失去了平衡,不再是AVL树如果一棵
2022-05-09 18:05:55
510
2
原创 算法 动态规划 打家劫舍
分析得出,dp[k] = max(dp[k-1],dp[k-2]+nums[k])int rob(vector<int>& nums){ int n = nums.size(); if (n <= 0) return 0; if (n == 1) return nums[1]; vector<int> dp(n, 0); dp[1] = nums[1]; dp[2] = max(nums[1], nums[2]); for (int i = 3; i.
2022-05-08 20:46:09
471
原创 算法 二叉树 BST树
二叉排序树BST树的定义BST树结构BST树的创建递归中序遍历非递归中序遍历逆向非递归中序遍历删除结点BST树的定义BST树又称为:二叉排序树,二叉搜索树二叉搜索树或者是一颗空树,或者是具有下列性质的二叉树每个结点都有一个作为搜索依据的关键码(key),所有结点的关键码互不相同左子树(如果存在)上所有结点的关键码都小于根节点的关键码右子树(如果存在)上所有结点的关键码都大于根节点的关键码左子树和右子树也是二叉搜索树总结:如果对一颗二叉搜索树进行中序遍历,可以按从小到大的顺序,将各结
2022-05-07 18:38:07
2296
原创 算法 二叉树的遍历、查找与判断
二叉树的遍历非递归中序遍历非递归后续遍历非递归先序遍历二叉树层次遍历非递归中序遍历void NiceInOrder(BtNode* ptr) //非递归中序遍历{ if(ptr == nullptr) return; std::stack<BtNode*> st; while (ptr != nullptr || !st.empty()) { while (ptr != NULL) { st.push(ptr); ptr = ptr->leftchild
2022-05-06 17:33:16
577
原创 算法 二叉树
二叉树树的定义二叉树的概念二叉树的定义:二叉树的性质:存储表示代码实现结构定义遍历方式二叉树创建树的定义树是由n(n>=0)个结点组成的有限集合,如果n = 0,成为空树,如果n > 0,则有一个特定的称之为根(root)的结点,它只有直接后继,但没有直接前驱除根以外的其他结点划分为m(m >= 0)个互不相交的有集合T0,T1,…,Tm-1,每个集合又是一棵树,并且称之为根的子树,每棵子树的根节点有且仅有一个直接前驱,但可以有0个或多个直接后继结点的度:一个节点含有的子
2022-05-05 20:00:07
878
2
原创 算法 动态规划 01背包问题
01背包问题分析代码实现从前往后拿,递归实现非递归实现非递归实现,自上向下填充允接上一文章内容:算法 动态规划: link.问题分析按照普通思维,首先想到应该为贪心算法,也就是计算每个物品重量价值比,将性价比高的物品装入背包,但是这并不是该问题的最优解,因为物品不是可分割的,不能按照重量价值比进行选择这道问题的最优解应该通过动态规划求解,那么其递归方程式为:在这里f(i,j),记为当背包容量为 j,现有 i 物品可拿,所能装进背包的最大价值再者我们举例说明,假设背包总容量为8,现在有四件
2022-05-04 15:34:49
1427
原创 C++ 可变参数模板
可变参数模板C++11 增强了模板功能,在C++11之前,类模板和函数模板只能含有固定数量的模板参数,现在C++11中的新特性可变参数模板允许模板定义中包含0到任意个模板参数,可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号“…”省略号的作用有两个:声明一个参数包,这个参数包中可以包含0到任意个模板参数在模板定义的右边,可以将参数包展开成一个一个独立的参数template<class ... T>vo
2022-05-02 20:24:10
2243
原创 C++ 可调用对象
可调用对象概念可调用对象包装器——std::functionstd::bind 绑定器概念在C++中,存在“可调用对象”这么一个概念,准确来说,可调用对象有如下几种定义:是一个函数指针是一个具有operator()成员函数的类对象(仿函数)是一个可被转换为函数指针的类对象是一个类成员(函数)指针void func() { cout << "func" << endl;}struct Foo{ void operator()() { cout <
2022-05-02 19:37:41
1465
原创 C++ ThreadPool
线程池半同步半异步线程池半同步半异步线程池再处理大量并发任务的时候,如果按照传统的方式,来一个任务请求,对应一个线程来处理请求任务,大量的线程创建和销毁将消耗过多的系统资源,还增加了线程运行环境切换的开销,而通过线程池技术就可以很好地解决这些问题;线程池技术通过再系统中预先创建一定量的线程,当任务请求到来时从线程池中分配一个预先创建的线程去处理任务,线程在处理完任务之后还可以重用,不会销毁,而是等待下次任务的到来这样,通过线程池能避免大量的线程创建和销毁动作,从而节省系统资源,这样做的一个好处是,对于
2022-05-02 11:03:09
1933
原创 C++ STL概述
STLSTL概述STL概述STL是”Standard Template Library“的缩写,中文译为”标准模板库“;STL是C++标准库的一部分,不用单独安装C++对模板(Template)支持的很好,STL就是借助模板把常用的数据结构及算法都实现了一遍,并且做到了数据结构和算法的分离;例如,vector的底层为顺序表(数组),list的底层为双向链表,deque的底层为循环队列,set的底层为红黑树,unordered_map(hash_map)的底层为哈希表STL包含:容器类各种数据
2022-04-30 19:58:55
263
原创 C++ 对象池 ObjectPool
template<class _Ty>class ObjectPool{ enum { nPollSize = 4 }; //最多三个对象protected: struct _Node { _Node* next; }; _Node* front; //头 _Node* rear; //尾private: void ReFillPool() //填充 { size_t total = sizeof(_Node) + sizeof(_Ty); for (in
2022-04-30 19:49:03
1457
原创 C++ 对象与对象的关系
对象与对象的关系依赖关联聚合在一个系统中,一个对象可能与不同的对象相关,以下是不同的关系依赖(Dependency)使用一个关联(Association)使用一个聚合(Aggregation)有一个组合(Composition)有一个,“用…来实现”继承(Inheritance)是一个类模板(Class template)依赖依赖(Dependency):使用一个class Book{};class Food{};class Human{public: void Read
2022-04-30 15:38:35
1447
原创 C++ Thread 信号量
信号量信号量实现生产者消费者MySemaphore信号量实现生产者消费者int g_num = 0;std::binary_semaphore semp(1);std::binary_semaphore sems(0);void P(int i){ for (int i = 0; i < 10; ++i) { semp.acquire(); //1 -> 0 P操作 g_num = i; cout << "P:" << g_num &l
2022-04-28 18:57:13
1459
原创 C++ Thread 死锁
死锁死锁示例如何解决死锁死锁示例线程A与线程B陷入无休止的阻塞状态std::mutex mx1;std::mutex mx2;void thread_func1(){ unique_lock<std::mutex> lc1(mx1); cout << "1号锁" << endl; std::this_thread::sleep_for(std::chrono::microseconds(200)); unique_lock<std::mut
2022-04-27 17:18:23
832
原创 C++ Thread 生产者消费者模式
生产者消费者模式锁的粒度双端队列生产者消费者模式const int MAX_ITEM = 20;std::mutex mx;std::condition_variable cv;class Queue{public: Queue() {} ~Queue() {} void put(int val, int index) { std::unique_lock<std::mutex> lock(mx); while (q.size() == MAX_ITEM)
2022-04-26 18:29:34
635
原创 C++ Thread
Thread 线程库线程的创建detach 句柄独立线程资源转移sleep_ for全局函数线程化joinablehardware_concurrency线程的互斥原子操作定义互斥锁try_lockrecursive_mutex 递归锁线程的创建void funa(){ cout << "funa()" << endl;}void funb(int a){ cout << "funb(int a)" << endl;}void func(i
2022-04-26 11:11:31
3444
原创 C++ C11新特性
C11新特性move移动构造如何实现未定义类型C++ 类型强转模板编译分裂性move移动构造如何实现class MyString{ char* str;public: MyString(const char* p = NULL) :str(NULL) { if (p != NULL) { int len = strlen(p) + 1; str = new char[len]; strcpy_s(str, len, p); } } MyString(const
2022-04-25 17:38:34
479
6
原创 C++ 空间的配置与释放 std::alloc
空间配置与释放第一级配置器第二级配置器对象建立前的空间配置,和对象析构后的空间释放,由<stl_alloc.h>负责,SGI对此的设计哲学如下:向 system heap 系统堆空间申请考虑多线程情况考虑内存不足的情况考虑过多小块的内存可能造成内存碎片的问题C++ 的内存分配动作是 ::operator new(),而内存的释放动作是::operator delete()来进行,我们在设计过程中,这两个函数由C的malloc()和free()函数代替,因为 ::operator
2022-04-25 08:50:28
621
原创 C++ 模板中的问题
区分模板函数区分裸指针与智能指针通过特化模板进行区分template<class T>struct my_class{ my_class<T>(); static const bool value = true;};template<class T>struct my_class<T*>{ my_class<T>(); static const bool value = false;};template<class
2022-04-24 20:39:09
347
原创 C++ 迭代器萃取
迭代器萃取迭代器型别迭代器类型迭代器萃取迭代器型别value type 值类型,是指迭代器所知物件的型别difference type 相差型别,表示两个迭代器之间的距离reference type 引用类型,从迭代器所指之物的内容是否允许改变pointer type 指针类型,迭代器所指之物的地址iterator_category 迭代器的相应型别迭代器类型Input Iterator 只读迭代器Output Iterator 可写迭代器Forward Iterator 正
2022-04-22 11:05:05
460
原创 C++ lambda表达式
lambdalambda 表达式简介lambda 表达式的基本概念和基本用法lambda 表达式简介lambda表达式是C++11最重要也最常用的一个特性之一,其实在C#3.5中就引入了lambda,Java8中也引入了lambda表达式lambda 来源于函数式编程的概念,也是现在编程语言的一个特点,有如下优点:声明式编程风格:就地匿名定义目标函数或函数对象,不需要额外写一个命名函数或者对象,以更直接的方式去写程序,好的可读性和可维护性简洁:不需要额外再写一个函数或者函数对象,避免了代码膨胀和
2022-04-21 12:42:56
10655
2
原创 C++ STL map set
mapmap 简介unordered_map 无序mapmap 的插入multimap 多重mapmap 输出findequal_rangeset 容器map 简介map底层由排序二叉树,也就是红黑树实现我们来看一段示例代码,通过map统计string中各字符串出现的次数int main(){ string stra[] = { "map","deque","queue","vector","list","map","vector","map" }; std::map<string,
2022-04-21 10:35:19
1154
原创 C++ STL duque
duquedeque 简介deque 的布局deque 和 vector 的区别deque 简介deque 是由一块一块的固定大小的连续空间构成(块与块之间是不连续),一旦有必要在deque的前端或尾端增加新的空间,便配置一块固定大小的连续空间,串联在整个duque的头端或尾端deque的最大任务,便是在这些分块的固定大小连续空间上,维护其整体连续的假象,并提供随机存取的接口(随机迭代器),代价则是迭代器架构较为复杂deque采用一块所谓的_M_map(注意,不是STL的map容器)作为主控,这里所
2022-04-20 13:41:26
624
原创 C++ STL list
Listlist 的介绍list 的使用list 的创建访问、push_front、erase、unique、removelist 与 vector 的区别总结list 的介绍list是序列容器,允许在序列中的任何位置执行固定O(1)时间的插入和删除操作,并在两个方向上进行迭代list容器使用双链表实现,双链表将每个元素存储在不同的存储位置,每个节点通过next,prev指针链接成顺序表list与其他基本标准序列容器(array、vector和deque)相比,list通常在容器内的任何位置插入、
2022-04-20 12:35:16
478
原创 C++ STL vector
vectorvector简介vector 的使用初始化operator[] 与 at 对容器元素访问reserve 、 resize 、assignpush_back、insertemplace_back 原位构造vector简介vector 是表示可以改变大小的数组的序列容器vector 与数组一样,元素使用连续的存储空间,就可以使用常规指针,指向其元素,使用偏移量来访问存储空间中的元素vector 与数组不同的是,vector 的大小可以动态变化,容器会自动扩容存储空间vector 使用一个
2022-04-19 17:16:07
663
原创 C++ 智能指针的两种创建方式
两种创建方式std::shared_ptr<Object> op1(new Object(10));std::shared_ptr<Obejct> op2 = std::make_shared<Object>(20);这样两种不同的智能指针构建方式,其内存结构是不同的对于第一种方式来说,op1有一个ptr指针和一个删除器(mDeletor),ptr指针指向引用计数对象(RefCnt),引用计数对象有mptr指针和引用计数(ref),mptr直指向Object对象
2022-04-17 11:47:27
3948
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人