
数据结构
文章平均质量分 76
ArchyLi
一个学习路上人。当然还差很多。
展开
-
【C++】优先级队列的模拟实现
优先级队列是在堆的基础上进行的一个扩展,主要是运用大堆来实现优先级队列,让优先度高的出队列,最大优先队列可以选用大堆,最小优先队列可以选用小堆来实现。 下面以最大优先队列来讲解其原理。 最大优先队列一般包括将一个元素插入到集合S中、返回集合S中具有最大key的元素、返回并删除集合S中具有最大key的元素等。 堆的实现代码如下 下面给出实现代码:#include <vector>#inclu原创 2017-05-13 18:38:00 · 1178 阅读 · 0 评论 -
深入哈希表(二)--开放定址法实现哈希表
在上一篇文章中,我们主要是简介了哈希表,下文我们来实现开放定址法的哈希表。 开放定址法主要有两种方法,一种是线性探测,一种是二次探测,本文主要针对这两种方法进行介绍。开放定址法–闭散列方法一、线性探测(1)线性探测是什么设给出一组元素,它们的关键码为:37,25,14,36,49,68,57,11,散列表为HT[12],表的大小m = 12,假设采用Hash(x) = x % p; // (p原创 2017-11-08 23:40:59 · 1372 阅读 · 0 评论 -
深入哈希表(三)--拉链法(哈希桶)实现哈希表
一、简介为了解决线性探构造哈希表所出现的大量哈希冲突,我们采用了另外一种方法,便是开链法。而在SGI版本的STL中调用的也正是哈希桶的实现方法。注意:开链法实现哈希表的时候会出现很多很多的错误,比如各种模板错误,此时需要耐心,慢慢调整。同时又为了扩展hash_map与hash_set更改了一些模板参数,所以经过调试错误的过程,绝对会对模板有一个全新的认识。二、拉链法实现原理:采用了由N个头指针构成的原创 2017-11-11 15:43:42 · 3490 阅读 · 1 评论 -
深入哈希表(四)--哈希表封装UnorderMap、UnorderSet
在前几章内容我们主要介绍了hash_table的实现原理,包含了线性探测、二次探测,那么接下来我们来实现一下unordermap、unorderset。一、概述unordermap、unorderset在底层是使用Hash_table的拉链法(哈希桶)的方法,即unordermap、unorderset的实现依靠了Hash _Table,所以我们来简单的封装下之前用开链法实现的Hash_Table原创 2017-11-12 00:40:37 · 694 阅读 · 0 评论 -
【BSTree】深入理解二叉搜索树
一、概念二叉搜索树又称为二叉排序树,主要满足以下性质的二叉树则成为二叉搜索树:若它的左子树不为空,则左子树上所有结点的值都小于根结点的值。若它的右子树不为空,则右子树上所有结点的值都大于根结点的值。它的左右子树都是二叉搜索树。 空树为二叉搜索树。二、二叉搜索树的操作(1)二叉搜索树的查找二叉搜索树的查找既是从一条路径一直向下,直到找到所需要的结点值的位置,或者为NULL值。根据二叉搜索树的原创 2017-11-02 17:47:53 · 1237 阅读 · 0 评论 -
大数据处理
大数据处理并不要求手写代码,更重要的是叙述出来思路和方法,主要的解题思路有以下两个:方法:看能否用特殊的数据结构解决(位图、布隆过滤器、堆(TOP K 问题))哈希切分题目⒈ 给一个超过100G大小的log file,log中存着ip地址,设计算法找到出现次数最多的ip地址?解决方法:哈希切分。将100G的文件分成1000份,通过同一个散列函数映射到相应的文件,此时同一个ip一定会映射到同一原创 2017-11-14 22:03:00 · 504 阅读 · 0 评论 -
C++位图详解(BitMap)
题目:给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快 速判断一个数是否在这40亿个数中。 【腾讯】思路:这道题首先要判断40亿个不重复的无符号整数究竟占多大的内存,因为太大的内存我们无法加载到现有的计算机中。一个整数是4个字节,40亿个整数就是160亿个字节,也就相当于16G内存,就一般的计算机而言很难实现这个加载,所以我们可以采取以下两种方案,一种是分割,一种是位图。方法:①分割原创 2017-11-19 11:26:13 · 19001 阅读 · 27 评论 -
大数据处理--布隆过滤器的原理与实现
一、定义如果向之前的章节,40亿个不重复无符号的整形判断是否存在,我们可以选择用位图来解决,那么如果是40亿个邮箱地址我们该如何解决呢。因此我们便想着能否把邮箱地址按照一定的方式映射到一个集合呢,接着我们只需要看点是否为1就知道这个集合有没有它了,这便是布隆过滤器的基本思想。我们采用字符串哈希函数来处理字符串,但是一个字符串哈希函数可能会产生很多的冲突,因此我们可以采用多个哈希函数来解决这点。二、布原创 2017-11-20 00:13:03 · 1417 阅读 · 2 评论 -
【c++】模拟实现堆
这次我们来模拟实现堆,首先堆是一个完全二叉树,每个元素都有一个关键码,储存相应的数据,堆分为最大堆和最小堆。最大堆:最大堆任意一个节点都大于它左右孩子的关键码,堆顶元素最大。最小堆:最小堆任意一个节点都小于它左右孩子的关键码,堆顶元素最小。因此我们得出以下结论:堆存储在下标为0开始计数的数组中,因此在堆中给定小标为i的结点时:1、如果i=0,结点i是根节点,没有双亲节点;否则结原创 2017-05-13 18:20:09 · 637 阅读 · 0 评论 -
【BTree、B-树】B树的C++实现
一、B树的概念B树是平衡的多叉树,一个节点有多于两个(不能小于)结点的平衡多叉树。由于B树倒着生长所以平衡。缺点:浪费空间二、B树满足以下性质:1、根结点至少有两个孩子。[2,M]个孩子 2、每个非根结点有【(M/2),M】个孩子。 3、每个非根结点有【(M/2-1),M-1】个关键字,并且以升序排序。 4、每个结点孩 5、key[i]和key[i+1]之间的孩子节点的值介于key[i]、k原创 2017-11-25 15:40:51 · 4226 阅读 · 0 评论 -
详解并查集
一、概念并差集主要用来求解不相交集合的问题,主要针对于合并和查找两种算法。二、并差集实现并差集的实现主要包含了三个部分:初始化并差集。合并并差集。 查找并差集。 (1)并差集的初始化并差集的初始化是对单个数据建立了一个单独的集合,每个集合应该包含以下两个数据:这个集合所表示的数据。这个集合的根集合所在位置。由以上两个数据,一般的并差集的结构一般有两种表示形式:结构体构造。数组构造。原创 2017-11-26 22:25:47 · 889 阅读 · 0 评论 -
排序--插入排序的实现
一、简介插入排序类似于我们玩扑克牌,如果想要让我们手中的牌有序,那么当我们从牌堆中抽出一张牌放入自己手中的牌组内时,需要把这张牌和手中最大的牌开始向前比较,直到找到一个大于前面的牌小于后面一张牌的情况下插入即可。二、时间复杂度逆序时间复杂度最坏,因为每次插入都需要移动数据,所以时间复杂度为 O(N^2)有序最好,不需要移动数据,所以时间复杂度O(N)三、实现插入排序的原创 2017-12-01 23:56:34 · 513 阅读 · 0 评论 -
排序--希尔排序的实现(shellsort)
一、简介希尔排序是插入排序的一种,它是插入排序的一种优化,它在插入排序之前使用了一个预排序,使整个数组接近有序,方便后续的排序。 在网上看到一个动态,这个动图很形象的说明了希尔排序的思想,所以我把它放出来。二、时间复杂度时间复杂度O(N^1.3),相比于直接插入排序,在顺序情况下不如直接插入排序。三、实现1. 第一个阶段预排序(接近于有序)采用分组来先排序一遍,使小的原创 2017-12-01 23:36:11 · 699 阅读 · 0 评论 -
AVL树的C++实现
AVL树在数据结构中应该算是比较难的一种数据结构了,因为其中有多种插入情况而分成了不同的情况。一、概念AVL树是一种高度平衡的二叉搜索树,是为了降低二叉树的高度减少平均搜索长度。 相比于“二叉搜索树”,它的特点是在AVL树中任何结点的左右子树高度差不超过1。 AVL树如果右N个结点,其高度为lgN,平均搜索时间复杂度为O(lgN).二、AVL树的性质左子树和右子树的高度之差的绝对值不超过1.原创 2017-11-01 00:59:44 · 988 阅读 · 0 评论 -
一个数组实现两个栈
看到这个题目,大概会想到三种方法实现:(1)用奇数位下标存放一个栈的内容,用偶数位下标存放另外一个栈的内容。(2)从数组的中间一分为二,左边是一个栈,右边是一个栈,分别向两边延伸,栈底都是中间,栈顶向两边。(3)数组的两边分别做两个栈的栈底,两个栈向中间生长。简单的分析后,我们知道其他两种方法在运用的过程中总会产生更多的空间浪费,所以我们认为第三种方法是最好的,下面我们给出第三种方法的实现:代码如下原创 2017-10-24 00:40:51 · 827 阅读 · 0 评论 -
pair、map、set、multiset、multimap用法简介
一、pair简介在介绍这几种容器之前,我们先来看下pair,pair是一种模板类型,其中包含了两个数据值,两个数据的类型可以不同,定义如下: pair<int, string> a;表示a中有两个数据类型,一个是int类型,一个是string类型的,如果在创建pair时候没有对其初始化,则调用默认的构造函数对其初始化。也可以按照以下的方式在定义的时候进行初始化pair<int, string> a原创 2017-10-31 18:05:09 · 1192 阅读 · 0 评论 -
稀疏矩阵的压缩存储
#include #include using namespace std;templateclass SparseMatrix{public: // 稀疏矩阵的压缩存储 SparseMatrix(int* array, size_t row, size_t col, const T& invalid) : _row(row) , _col(col) , _inval原创 2017-05-09 18:12:40 · 756 阅读 · 0 评论 -
二叉树的实现
此二叉树主要用孩子表示法,递归创建二叉树。#include #include #include #include using namespace std;templatestruct BinaryTreeNode{ BinaryTreeNode(const T& value) : _value(value) , _pLeft(NULL) , _pRight(NULL原创 2017-05-21 22:51:27 · 630 阅读 · 0 评论 -
【C++】二叉树遍历--递归与非递归实现
1、二叉树前序遍历前序遍历主要顺序是先遍历根节点,再遍历左节点,最后遍历右结点1.1非递归实现void PreOrder_Nor1()//循环{ cout << "PreOrder_Nor: "; _PreOrder_Nor1(_pRoot); cout << endl;}void _PreOrder_Nor1(Node* pRoot)//先将左子树全部访问并入栈,再依次出原创 2017-05-21 23:19:46 · 528 阅读 · 0 评论 -
【C++】Huffman树的实现
介绍huffman树之前我们先来看下如下几个基本概念1、路径和路径长度路径:我们定义从A节点到B节点所经过的分支序列称为从A节点到B节点的路径。路径长度:路径中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。二叉树的路径长度:从二叉树的根节点到二叉树所有节点的路径长度之和,称为二叉树的路径长度。2、结点的权及带权路径长度节点的权原创 2017-05-21 23:48:51 · 2840 阅读 · 0 评论 -
两个栈实现一个队列
栈:先进后出的一种数据结构。队列:先进先出的一种数据结构。此时如果我们先有一个栈是不够的,我们只能把先入栈的元素后出来,后面入栈的元素先出来。这是我们便想如何才能实现一个先进先出的结构呢。看下图:我们先把元素倒入S1栈中,在把S1栈中的元素逐个压栈到S2里面,再从S2出栈,即可达到先入栈的元素先出。此时我们可以有一个小优化,最后一个元素X1可不入S2减少一次压栈的操作。原创 2017-07-21 16:58:47 · 489 阅读 · 0 评论 -
两个队列实现一个栈
栈:先进后出队列:后进先出方法一:如何用两个队列实现一个栈呢?我们可以把一个队列里面的内容放入第二个队列里面,此时要剩余一个,这剩下的一个可以直接出栈,再把队列2里面的元素放回队列1, 重复即可达到栈的要求#include#include using namespace std;template class Cstack{public: Cstack(void)原创 2017-07-22 13:09:06 · 595 阅读 · 0 评论 -
【每日一题】实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
这道题有两种实现方式方法一:用两个栈来实现两个栈实现的主要思路是,一个栈存放数据,一个栈存放最小值。压栈操作:(1)我们先向S1压栈一个数据(2)再向S1压入第二个数据,如果此时栈S2为空,并且把需要压栈的元素data和S2的栈顶元素进行比较,如果此时需要压栈的元素小于等于S2栈顶元素,把元素也压入栈2,否则不用管出栈操作:判断S1栈顶元素与S2栈顶元素是否相等,相原创 2017-07-22 14:45:03 · 3392 阅读 · 0 评论 -
【每日一题】元素出栈、入栈顺序的合法性。如:入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1),则合法。
题目:元素出栈、入栈顺序的合法性。如:入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1),则合法。入栈的序列(1,2,3,4,5),出栈序列为(4,5,2,3,1),则不合法。这道题我们可以创建两个栈(感觉有点类似两个栈实现一个队列),需要几个数字放在前面即把S1的栈顶元素取几个放在S2里面即可。出栈时候先判断S2是否为空,不为空则从S2栈顶元素逐个取出,再从S1中原创 2017-07-22 18:29:20 · 7917 阅读 · 0 评论 -
C++实现红黑树
红黑树简介红黑树是一个高效的平衡搜索树,保证最长路径不超过最短路径的两倍,因而近似平衡,保证了高度,也就保证了效率。增删查改时间复杂度都是O(logN)性质:每个结点不是红色就是黑色的。 根结点是黑色的。如果一个结点是红色的,则它的两个子节点是黑色的(没有连续的红结点)对于每个结点,从该结点到其所有后代叶节点的简单路径上,均包含相同数目的黑色结点(每条路径的黑色节点的数目相等) 每个叶子结原创 2017-10-28 01:39:44 · 816 阅读 · 0 评论 -
深入哈希表(一)--哈希表的简介(Hash_Table)
一、理解Hash_Table哈希表是从集合A到集合B的映射,可被视为一种字典结构,这种结构用意在于提供常数时间的基本操作。理想情况下,一次就能直接从哈希表中搜索到需要的元素,因为我们在元素的存储位置和它的关键码之间建立了一个对应的函数关系。我们可以通过这个函数关系,在插入的时候按计算出来的位置存放,在读取元素的时候通过这个函数进行计算位置,在对找到的位置进行读取即可。哈希并不等于哈希表,哈希是算法,原创 2017-11-08 22:59:08 · 887 阅读 · 0 评论 -
【C++】模拟实现栈
一、栈简介在数据结构中,栈是很特殊的一种结构,它是先进后出的存储结构,进行数据的插入和删除的一段为栈顶,另外一端为栈底。 栈又被称为后进先出的线性表。 由于栈是线性表,所以线性表的存储结构对于栈同样适用。栈分为顺序栈和链式栈两种,两种结构存储不同,所以相对应的基本运算也有所不同。 顺序栈和链式栈区别:1、 顺序栈有“上溢”和“下溢”的概念,“下溢”本身可以表示栈为空栈,因此可以表示为栈的转移条原创 2017-10-23 19:11:31 · 832 阅读 · 0 评论 -
【C++】模拟实现队列
一、队列简介队列是一种只允许在一段进行插入,另外一段进行删除的特殊线性表,允许删除操作的一端称为队头,允许插入操作的一端称为队尾。队列又被称为先进先出的线性表。与栈类似,队列也有两种存储结构,一种是顺序存储,一种是链式存储,前面一种称为顺序队列,后面一种称为链队。此处要注意顺序队列的溢出现象:(1)“下溢”现象:当队列为空时,做出队列的运算产生的溢出现象。(“下溢”是正常现象,原创 2017-10-23 19:18:31 · 1263 阅读 · 0 评论 -
排序--选择排序的优化和实现
一、简介选择排序的思想很简便,排序过程也很直观。选择排序是一种不稳定的排序算法。二、时间复杂度三、算法原理每一次循环调出来一个最大的或者最小的元素放在整个数组的最前面或者最后面即可完成整个排序。四、选择排序的优化我们知道,按照选择排序的思想,每次遍历都会选择出来一个最大(或者最小)的元素放在数组的一端,那么我们可以这么思考一下:我们为什么不能在遍历出来一段空间内的一原创 2017-12-01 23:51:19 · 609 阅读 · 0 评论