数据结构
文章平均质量分 96
数据结构
凌星An
1
展开
-
[数据结构、C++]:并查集
概念:并查集是一种树型的数据结构,用于处理一些不相交集合的合并和查询问题。在使用中常常以森林来表示,能很方便地同时维护很多集合。其核心思想是记录每个结点的父亲结点是哪个结点。举例理解:有三个家庭去组团旅游之前互不认识,第一个家庭是 A 、B、 C 第二个家庭是 D、E、F 第三个家庭是 G、H、I;所以这时候三个团体可以用三个树来表示经历了一天的相处,A和D十分熟悉,相约晚上两家共进晚餐,那么到了晚上就可以用两棵树进行表示那么我们怎么表示森林呢?用下面的规则进...原创 2020-09-07 22:56:36 · 311 阅读 · 0 评论 -
STL的简单了解(六大组件)
STL提供了六大组件,彼此可以组合套用容器:就是各种数据结构 eg:vector 、list、deque等等算法:各种常用的算法 eg: sort 、swap等等迭代器:所有的STL容器都附带有自己专属的迭代器;并且原生指针也是一种迭代器仿函数:行为类似函数;从实现的角度看,仿函数是一个重载了operator()的类或者类模板配接器:一种用来修饰容器或仿函数或迭代器接口的东西 eg:queue、stack空间配置器:负责空间配置与管理。从实现角度来看,配置器是一个实现了动...原创 2020-10-24 22:12:17 · 451 阅读 · 0 评论 -
图的简单了解
基础概念:图:就是一种有顶点集合和顶点间的关系组成的一种数据结构;也就是图保存着两个集合,一个是顶点的集合,另一个是顶点之间关系的集合图可以分为有向图和无向图,顾名思义,有向图是指顶点与顶点之间相连的边是有方向的;而无向图则表示顶点与顶点之间相连的边是没有方向的。如下图所示,在有向图中,连接A、B的两条边并不等价,因为指向的方向是不同的。完全图:是指顶点集合任意两个顶点都互相指向有n个顶点的集合,在有向图中,边的个数为n*(n-1)的图,为完全图。(每个顶点又要指向其余的n..原创 2020-09-11 17:21:20 · 502 阅读 · 0 评论 -
哈希第五弹:哈希应用之布隆过滤器
前言:我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。问题来了,新闻客户端推荐系统如何实现推送去重的? 用服务器记录了用户看过的所有历史记录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。 如何快速查找呢?如何我们使用哈希表的话,如果太多的新闻,所需要的内存也是个巨大的问题但是我们要使用位图的话,哈希冲突就是一个不可避免的问题!由于推送新闻,我们允许有一定的错误发生!我们就可以将哈希表和位原创 2020-07-10 19:27:49 · 344 阅读 · 0 评论 -
哈希第四弹:哈希的应用之位图
前言:不知道大家之前有没有了解过位图这个概念。而我初次知道位图这个概念的时候,大概是学习进程通信,信号的时候,用一个位标识一个信号;在信号的注册过程中,如果有该信号则该对应的比特位标志为1.信号注销的时候,该对应比特位更改为0.这个过程就类似于我们给定一个数列该数列为0~10以内的数字例如:1,3,7,5,4,7让你判断哪个数字在数列中出现过!我们的做法无异于开一个大小为11数组,全初始化为0,如果数字出现过,该对应位置的值改为1,表示出现过。最后遍历这个数组我们就可以知道答案。而位图的理原创 2020-07-09 15:59:37 · 196 阅读 · 0 评论 -
哈希第三弹:解决哈希冲突之开散列以及unordered_map和unordered_set的自我实现
前文:解决哈希冲突,我们有闭散列和开散列两种。闭散列的线性探测,容易使冲突堆积在一起,因而会造成搜索效率的下降。而二次探测在一定程度上解决了线性探测的问题,但是随着会带来空间浪费的情况。而本文我们所要讲的开散列,既不会造成冲突聚堆的情况,也不会带来空间浪费的问题。这种优势源于开散列的桶结构。开散列(链地址法、开链法)对关键字集合用散列函数计算散列地址,具有相同地址的关键码归于同一个子集合,每一个子集和称为一个桶,各个桶中的元素通过一个单链表连接起来,各链表的头结点存储在哈希表中。...原创 2020-07-09 11:51:23 · 678 阅读 · 0 评论 -
哈希第二弹:避免哈希冲突详解及其代码粗略实现哈希表
前引:我们在哈希第一弹中提到了避免哈希冲突的三种方法,在本篇博文中我们对他们进行更加详细的了解哈希冲突的解决方法闭散列(开放定制法):当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以把关键字存放到冲突位置中的“下一个”空位置中去。如何寻找下一个空位置呢?线性探测:从发生冲突的位置开始,依次向后探测,直到寻找下一个空位置为止二次探测:从发生冲突的位置开始,找下一个空位置,查找...原创 2020-07-05 16:05:57 · 297 阅读 · 0 评论 -
哈希第一弹:哈希的概念、哈希函数以及哈希冲突的解决方法
哈希的概念:哈希表查找的基本思想是:根据当前带查找数据的特征,以记录关键字为自变量,设计一个哈希函数,以该函数按关键码计算该元素的存储位置,并按此存放;查找时,有同一个函数对给定值key计算地址,将key与地址单元中元素关键码进行比较,确定查找是否成功。哈希方法中使用的转换函数称为哈希函数,按这个思想构造的表称为哈希表(散列表)从上面的概念,构建哈希表关键是有哈希函数。那么我们来看看常见的哈希函数有哪些?常见哈希函数:直接定制法:取关键字的某线性函数为哈希地址:Hash...原创 2020-07-03 14:10:37 · 802 阅读 · 0 评论 -
map&set底层的自我实现
map#pragma once#include"RBTree.h"namespace Map{ template<class K, class V> class map{ struct MapKofValue{ const K& operator()(const pair<K, V> data) { return data.first; } }; public: typedef RBTree<K, pa原创 2020-07-06 14:09:51 · 137 阅读 · 0 评论 -
map和set的接口及其使用
set:set是一个key的搜索模型,底层是一个平衡二叉搜索树。应用于查找是否有key的场景插入:insertpair<iterator,bool> insert (const value_type& val);//插入一个值iterator insert (iterator position, const value_type& val);//在某个位置插入一个值template <class InputIterator> void in原创 2020-06-10 09:04:58 · 239 阅读 · 0 评论 -
STL中vector的底层实现
namespace MyVector{ template<class T> class vector{ public: typedef T* iterator; typedef const T* const_iterator; iterator begin() { return _start; } iterator end() { return _finish; } const_iterator cbegin() const原创 2020-05-14 14:15:30 · 823 阅读 · 0 评论 -
[STL]list的底层实现
在看底层代码之前我们需要了解几个问题问题一:STL链表是一个什么结构?STL链表是一个双向循环链表。问题二:那么list类中怎么构建这样的一个双向链表呢?先构建一个无任何作用的头结点,如果链表需要新增节点,那么只需要插入即可问题三:解决完链表的构造,那么另一个重要的问题:迭代器的实现我们知道迭代器支持前置++ 、- -、后置++ 、- -以及解引用、->等等、*对于string、vector等容器、迭代器可以看作一个指针;++、- -等只需要指针进行++ 、–进行前后移动即可 。原创 2020-05-14 11:07:56 · 457 阅读 · 0 评论 -
string类成员函数的简单实现
namespace MyStringNew{ class String{ public: //构造,先申请内存,再将内容拷贝到申请的内存上面 String(char* str="") :_str(new char[strlen(str)+1]) { strcpy(_str, str); } ~String() { delete _str; ...原创 2020-04-24 10:54:46 · 396 阅读 · 0 评论 -
string接口的自我实现及其底层逻辑
namespace MyString{ class String{ public: //浅拷贝 //拷贝构造,缺省值为"" ;不能给nullptr指针 String(const char* str="") :_size (strlen(str)) { _str = new char[_size + 1]; strcpy(_str, str); ...原创 2020-04-22 17:20:25 · 196 阅读 · 0 评论 -
[STL]stack(栈)和queue(队列)底层实现
#pragma once#include<deque>底层利用双端队列当作适配器,实现自己的特性namespace stack{ template <class T, class Sequence = deque<T>> class stack{ public: bool empty() const { return c.empty(); } size_t size() const { return c.size(); }原创 2020-05-27 12:03:31 · 939 阅读 · 0 评论 -
[STL]priority_queue(优先队列)的底层实现
namespace queue{ template <class T> struct less{ bool operator()(const T& x1, const T& x2) { return x1 < x2; } }; template <class T> struct greater{ bool operator()(const T& x1, const T& x2) { return x1原创 2020-05-18 15:02:19 · 1079 阅读 · 0 评论 -
栈接口的自我实现
Stack.h文件:接口声明#pragma once#include<stdio.h>#include<stdlib.h>#include<assert.h>typedef int STDataType;// 支持动态增长的栈 typedef int STDataType;typedef struct Stack { STDataType* _...原创 2020-03-12 12:58:06 · 117 阅读 · 0 评论 -
平衡二叉树
概念:二叉搜索树又称为二叉排序树。他要不是一棵空树,要不是一个具备(它的左子树若不为空,则左子树上所有的节点的值全部小于根节点的值;它的有子树若不为空,则右子树上所有节点的值全部大于根节点的值)性质的二叉树。由定义我们可以知道二叉搜索树的中序遍历是有序的;并且二叉树中节点的值是独一无二的。代码实现:二叉树的插入、删除、查找template <class T>struct BSTreeNode{ struct BSTreeNode<T>* _left;原创 2020-06-09 09:30:23 · 134 阅读 · 0 评论 -
红黑树的自我实现
概念:红黑树是一棵二叉搜索树,每个节点是红色或黑色。通过对每条从根节点到叶子结点路径上的节点的颜色限制,确保没有一条路径长度会超过其他路径长度的两倍,因而是接近平衡的。所以AVL树比红黑树更集中。红黑树的特点:每个节点不是红色就是黑色 根节点是黑色的 如果一个节点是红色的,则它的孩子节点是黑色的 对于每个节点从该结点到其所有后代叶节点的路径上,均包含相同的黑色节点 每个叶节点(是指叶节点指向的空节点)是黑色的。小问题:红黑树概念中说确保没有一条路径会比其他..原创 2020-06-27 17:25:44 · 179 阅读 · 0 评论 -
AVL树的自我实现
AVL树的概念:我们都知道二叉搜索树如果有序插入,就会造成单支的现象,搜索效率就会降低(相当于在顺序表中查找数据,时间复杂度为O(N) );而AVL树就可以解决这个问题:AVL树就是一颗左右子树高度差不超过1的二叉搜索树。一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树: 它的左右子树都是AVL树 左右子树高度之差(简称平衡因子)的绝对值不超过1AVL树是高度平衡的,如果有n个节点,搜索时 时间复杂度为O(logn),而且稳定。AVL树的实现:AVL树是根据平衡二叉原创 2020-06-25 08:51:21 · 166 阅读 · 0 评论