数据结构
文章平均质量分 77
Everlasting2016
我流我的汗水,华丽如天花乱坠
展开
-
栈
一、栈1、只允许在末端进行插入和删除的线性表。栈具有后进先出的特性2、实现方法(动态):函数声明如下:templateclass Stack{public: Stack(); ~Stack();public: void Push(const T& s); void Pop(); size_t Size(); bool Empty(); T& Top();//原创 2016-04-08 12:46:21 · 307 阅读 · 0 评论 -
哈希表KV形式的二次探测
一、key_value形式的哈希表哈希表主要有两种形式:(1)key形式的,存入key的值,然后再去查找key的值(2)key_value形式的,存入key和对应的value的值,然后通过key来查找value的值,主要可以来实现KV字典查找对于以上两点本博客并不都一一实现,而是仅仅实现KV形式的二、K形式和KV形式的相互转换其实库中也有哈希表这两种的实现原创 2016-05-31 07:03:14 · 1172 阅读 · 0 评论 -
哈希表的开链法
一、开链法的优势闭散列最大的局限性就是空间利用率低,例如载荷因子为0.7,那么仍有0.3的空间未被利用使用开链法可以使载荷因子为1,每个链上都挂常数个数据,对于哈希表的开链法来说,其开的空间都是按素数个依次往后开的空间· 那么什么时候扩容呢?当每个链上都挂上数据之后,载荷因子为1的时候,就可以开始扩容了二、KV节点和仿函数的定义1、定义KV节点templatestruct原创 2016-06-01 09:16:10 · 2479 阅读 · 0 评论 -
堆的应用(优先级队列、海量数据处理、堆排序)
一、优先级队列1、基本思路其实可以使用队列来实现,但是不可避免的是Push()和Pop()操作,至少有一个的时间复杂度为O(N),另一个的时间复杂度为O(1),而使用对可以做到插入时时间复杂度为O(lgN),删除时时间复杂度为O(1)2、具体实现是通过适配器模式来实现的,通过对Heap的封装(1)堆的实现具体实现前面已有博客讲解过,这里就不具体讲解了代码如下:原创 2016-05-19 16:49:15 · 1315 阅读 · 0 评论 -
位图
一、题目.给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。 二、解题思路1、方法一;(直接遍历)将这些数字加载到内存中直接进行遍历,但是这种方法需要很大的内存空间,存入40亿个int类型的数字,大概需要开辟的内存大小大概是15G2、.方法二:(利用哈希表)利用哈希表可以直接进行定位,并且可以每个数字开辟一个char类型直原创 2016-05-20 10:08:29 · 418 阅读 · 0 评论 -
排序
一、插入排序1、直接插入排序void InsertSort(int arr[], int size){ if (arr == NULL || size <= 0) return; for (int i =1; i < size-1; i++) { int end = i;//一个有序序列的结尾 int tmp = arr[i+1]; while (end >= 0原创 2016-06-05 10:30:42 · 281 阅读 · 0 评论 -
非比较排序
一、什么是非比较排序区别传统的比较算法,不通过其中两个数的大小直接比较,来排序整个数列二、具体实现1、计数排序很好理解,就是对应每个数我们统计每个数字出现的次数,然后用一个直接定址的哈希表来存放数据,在通过遍历这个哈希表,进而就可以排好序了(1)代码实现void CountSort(int arr[], int size){ assert(arr); int mi原创 2016-06-06 07:48:20 · 1770 阅读 · 0 评论 -
并查集
在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。动态连通性一类问题的一种算法,使用到了一种叫做并查集的数据结构,称为Union-Find。建模思路:最简单而直观的假设是,对于连通的所有节点,我们可以认为它们属于一个组,因此不连通的节点必然就属于不同原创 2016-08-09 22:40:19 · 295 阅读 · 0 评论 -
布隆过滤器
布隆过滤器(Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的。它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Filter报告某一元素存在于某集合中,但是实际上该元素原创 2016-08-22 11:45:57 · 695 阅读 · 0 评论 -
二叉查找树中节点的删除
今天,在写数据结构的二叉查找树时,写到remove方法时,突然卡壳了。后来,打开书细看时,竟然耗费了不少时间才看懂。 现将思想记录下来,以免以后再次遗忘。 二叉查找树重要性质: 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。左子树上所有节点的关键码(key)都小于原创 2016-08-10 23:25:13 · 675 阅读 · 0 评论 -
排序之快速排序
一、基本思想 快速排序的基本思想都是大的数据往后放,小的数据往前放,key放在对应的正确的位置上,且由key划分的区间两边数据所在区间的位置都是正确二、递归实现1.方法一:双向扫描法两边同时扫描,begin遇到比key大的停下来,而end遇到比key小的停下来,然后两者交换,直到两个指针相遇(注意两个元素组成的有序区间的情况)void QuickSort(int arr[]原创 2016-06-04 07:38:08 · 472 阅读 · 0 评论 -
哈夫曼树
一、定义Huffman树,又称为最优二叉树,是加权路径长度最短的二叉树。简单的来说就是权值越大路径越短(权值),这样整体最优(权值*路径长度的和最小)二、证明huffman编码是最优编码设某个Huffman编码加权和为∑(Ai*Pi),若存在更优的非H编码,不妨设其中与H编码中权重Pi的位置Ai与Pj的位置Aj调换位置(Pi>Pj),则有Pi*Aj+Pj*Ai>Pi*Ai+Pj*A原创 2016-06-10 09:49:15 · 758 阅读 · 0 评论 -
key形式哈希表的线性探测
一、什么是key形式的哈希表简单的说就是通过key的来查找key的值二、线性探测简单的来说就是遇到哈西冲突就查找下一个位置,看位置上是否有数据,假如有则继续查找,假如没有则将数据放入到当前位置局限性:引发洪水式的冲突,冲突越来越多,找的越来越慢(因为找到的是一片冲突,找到空才停下来),效率低二、定义状态数组和仿函数1、定义状态数组由于哈希表中每个位置的传值不知道设置为什原创 2016-05-28 07:06:15 · 592 阅读 · 0 评论 -
对称矩阵及对称矩阵的压缩存储
定义:设一个N*N的方阵A,A中任意元素Aij,当且仅当Aij == Aji(0 压缩矩阵:(1)压缩存储称矩阵存储时只需要存储上三角/下三角的数据,所以最多存储n(n+1)/2个数据。(2)对称矩阵和压缩存储的对应关系:下三角存储i>=j, SymmetricMatrix[i][j] == Array[i*(i+1)/2+j]代码如下:函数声明如下:tem原创 2016-04-19 18:55:36 · 2204 阅读 · 0 评论 -
队列
队列1、队列值允许在表的队尾进行插入,在表对头进行删除。队列具有先进先出的特性。(队尾入数据,队头出数据)2、具体实现(单链表)节点定义:templatestruct Node{public: Node(const T& x) :_data(x) ,_next(NULL) {}public: T _data; Node* _next;};函数声明:原创 2016-04-08 13:07:28 · 276 阅读 · 0 评论 -
栈的应用1;后缀表达式求解
1、求解原理:遇到操作数,放入栈中,遇到操作符,从栈中取两个操作数计算,计算的结果再放入栈中2、为什么不将操作数放入字符串中?因为挨着放,例如:“12345”,不知道是1、2、3、4、5,还是12345或者y也可以在字符串中加入逗号,例如“1,2,3,4,5”3.逆波兰表达式求值程序定义枚举:enum Type{ OP_NUM, OP_SYMBOL, ADD,原创 2016-04-08 13:24:43 · 559 阅读 · 0 评论 -
两个栈实现一个队列
基本思路:队列有针对队头的操作,也就是说需要操作栈底的元素,直观的想到另外开辟一个栈,然后将前面的元素倒入新开辟的栈中,这样就可以操作栈的元素了,也就实现了对队头的操作大体思路基本一致,但是实现过程有小的不同,请开下面的详解:方法一:思路:有两个栈,s1作为存储空间,s2z作为临时缓存区,(1)入队时,将元素压入s1(2)出队时,将s1的元素逐个“倒入”(弹出并压入)s2,原创 2016-04-12 22:30:24 · 336 阅读 · 0 评论 -
两个队列实现一个栈
基本思路:(1)队列不能对队尾进行删除操作,而栈要对栈底进行删除操作,这句需要将对队列进行一步一步的pop()操作,取到队尾元素,将其删除,为了保证前面的顺序还可以复原,那么就需要另一个队列,来存储元素(2)其实不用像两个栈实现一个队列一样,push()在一个栈中,而pop()必须在另外一个栈中,因为两个栈中的元素顺序是不一样的,而队列而言,两个队列来回到是的顺序是一样的,所以对那个进原创 2016-04-13 15:24:38 · 407 阅读 · 0 评论 -
元素出栈、入栈顺序的合法性
题目如下:元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)基本思路: 很直观的一种想法,建立一个辅助栈,把输入的第一个序列中的数字一次压入该辅助栈,并按照第二个序列的顺序从该栈中弹出数字。判断思路:遍历出栈顺序中的元素,有两种情况 :(1)如果元素是栈顶的元素,则pop出来;(2)如果不是栈顶元素,则根据入栈顺序将原创 2016-04-13 15:38:46 · 2473 阅读 · 1 评论 -
一个数组实现连个栈
基本思路:两个栈共用一片空间,这就设计到怎么设计的问题,怎么可以合理的利用这片空间(1)从中间往两边增加,这样不栈底的位置设计不合理,便会造成空间的浪费(2)从两边往中间push(),可以合理的利用空间(3)还可以按照数组下标的奇偶进行push(),同样这样但两个栈的大小差距太大的时候,也会造成较大的空间浪费代码实现如下:(从两边向中间进行push)函数声明:templ原创 2016-04-13 16:14:29 · 354 阅读 · 0 评论 -
二叉树之遍历(递归和非递归解法)
一、前序遍历1、递归遍历:主函数:void PreOrder(){ _PreOrder(_root);}递归函数:void _PreOrder(Node* root){ if (root == NULL) return; cout _data << " "; _PreOrder(root->_left); _PreOrder(root->_right);}原创 2016-05-24 23:40:02 · 378 阅读 · 0 评论 -
实现一个具有GetMin功能的栈
题目:实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)基本思路:(1)建立两个栈,一个为普通的容纳数据的栈stackData,一个为stackMin的栈用来返回最小值(2)压入数据时,stackData直接压入数据newNum` stackMin若为空,直接压入数据newNum。若不为空若不为空,则则比较要压入数据n原创 2016-04-16 22:47:32 · 593 阅读 · 0 评论 -
二叉树之基本操作
一、存储结构1、静态结构只适合完全二叉树,或者一些节点缺省较少的情况,用数组来存储,对应下标的位置存储对应的值,如果缺省较多,则造成过多的空间浪费2.。动态结构(链式存储)分为二叉链和三叉连,三叉练主要是为了回溯,通过子节点找到父节点,本文主要实现的是二叉链二、节点的定义代码如下:templatestruct BinaryTreeNode{public: Bin原创 2016-05-02 23:18:53 · 509 阅读 · 0 评论 -
栈的应用之迷宫问题
1、原创 2016-04-18 18:35:39 · 411 阅读 · 0 评论 -
哈希表总结
一、哈希表/散列表简单的来说将数据按规律放,然后按照规律来查找的这么一个存放数据的表它通过一个关键值的函数将所需的数据映射到表中对应的位置来存放数据和访问数据这个映射的函数就叫做散列函数这个存放记录的表就叫做散列表二、构造哈希表的方法1、.直接定址法取关键字的某个线性函数为散列地址,Hash(Key)= Key 或 Hash(Key)= A*Key + B,A、B为常数原创 2016-05-27 08:00:57 · 1085 阅读 · 0 评论 -
AVL树
记得上次的博客中说到了二叉所搜树,也说到了他还说一种有欠缺的二叉树,当输入单调递增或单调递减的数据后,他会退化成链表,这样会严重影响效率,所以AVL树就被引出来了,下面就开始简单介绍AVL树吧。首先AVL树是一种严格的平衡二叉树,他要求所有节点所在的二叉树都满足一个条件:平衡因子不大于2,搜索二叉树也就接近满二叉树了,这个时候搜索的效率就比较高了,但是它也因此付出了很高的代价,那就是他会不断的原创 2016-08-24 15:30:59 · 477 阅读 · 0 评论