代码改变世界

随笔分类 -  数据结构

双层桶划分

2013-11-11 22:02 by youxin, 1114 阅读, 收藏, 编辑
摘要: 【什么是双层桶】事实上,与其说双层桶划分是一种数据结构,不如说它是一种算法设计思想。面对一堆大量的数据我们无法处理的时候,我们可以将其分成一个个小的单元,然后根据一定的策略来处理这些小单元,从而达到目的。【适用范围】第k大,中位数,不重复或重复的数字【基本原理及要点】因为元素范围很大,不能利用直接寻... 阅读全文

Bloom Filter

2013-11-10 12:15 by youxin, 904 阅读, 收藏, 编辑
摘要: Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员,这种检测只会对在集合内的数据错判,而不会对不是集合内的数据进行错判,这样每个检测请求返回有“在集合内(可能错误)”和“不在集合内(... 阅读全文

树状数组资料

2013-10-05 22:14 by youxin, 218 阅读, 收藏, 编辑
摘要: http://hawstein.com/posts/binary-indexed-trees.htmlhttp://dongxicheng.org/structure/binary_indexed_tree/http://www.cppblog.com/Ylemzy/articles/98322.html 阅读全文

XOR双向链表

2013-10-04 15:52 by youxin, 805 阅读, 收藏, 编辑
摘要: 这是一个数据结构。利用计算机的的位异或操作(⊕),来降低双向链表的存储需求。... A B C D E ... –> next –> next –> next –> A⊕C B⊕D C⊕E link(B) = addr(A)⊕addr(C), link(C) = addr(B)⊕addr(D), ..要求addr(D),使用:addr(D) = link(C) ⊕ addr(B)地址指针中存放的地址的异或。 比如B中就存放了A⊕C的值。这样从头开始便利时,我们需要知... 阅读全文

链表查找问题总结

2013-10-02 22:13 by youxin, 481 阅读, 收藏, 编辑
摘要: 问题1:找到链表中倒数第 k 个元素。由于链表无法得知其长度,一般的想法是首先遍历一遍得到长度len,然后再从头走len-k;就得到了倒数第k个元素。效率太慢。有一种比较好的方法。设2个指针pFirst,pSecond,首先让pFirst走k步。让两个指针有 k 步的遍历步距差值,这样当第一个指针指向最后时,第二个指针正好指向倒数第 k 个。其实遍历的次数和算法一相同。网上有一些文章误认为这种方式更高效,其实没有太本质的变化,只有常数的变化。具体来说,就是先让 ptrFirst 遍历了 k 个节点后,两个指针再开始一起遍历节点。问题2:找到链表的中间元素。与问题1类似,让pFirst以两部速度 阅读全文

利用宏来求结构体成员偏移值

2013-10-01 04:51 by youxin, 5516 阅读, 收藏, 编辑
摘要: 我们在书写C程序的时候,有时候需要根据结构体成员变量的地址,得到结构体的地址,特别是我们想用C来实现C++的继承特性的时候。我们对问题的分析如下:输入:一个结构体定义type,这个结构体中某个成员变量的名字member以及它的地址ptr输出:包含此成员变量的结构体的地址为了便于分析,我们给出一个实例来说明struct father_t {int a;char *b;double c;}f;char *ptr = &(f.b);//而不是 ptr = f.b; 这里ptr是b的地址,而不是它指向的地址。根据C语言对struct类型的存储特性,我们可以画这么一个图示:通过分析图示,我们可以 阅读全文

关于栈和队列的题目总结

2013-09-07 01:08 by youxin, 1099 阅读, 收藏, 编辑
摘要: 1.题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。这是google的面试题。我看到这道题目时,第一反应就是每次push一个新元素时,将栈里所有逆序元素排序。这样栈顶元素将是最小元素。但由于不能保证最后push进栈的元素最先出栈,这种思路设计的数据结构已经不是一个栈了。在栈里添加一个成员变量存放最小元素(或最小元素的位置)。每次push一个新元素进栈的时候,如果该元素比当前的最小元素还要小,则更新最小元素。乍一看这样思路挺好的。但仔细一想,该思路存在一个重要的问题:如果当前最小元素被pop出去,如何才能得到下一个 阅读全文

编程之美:编程判断两个链表是否相交

2013-09-05 13:56 by youxin, 3778 阅读, 收藏, 编辑
摘要: 编程判断2个链表是否相交(假设2个链表均不带环)解法二:利用计数的方法,如果我们能够判断2个链表中是否存在地址一致的节点,就可以知道这2个链表是否相交。一个简单的做法是对第一个链表的节点地址进行hash排序,建立hash表,然后针对第二个链表的每个节点的地址查询hash表,如果在hash表中出现,那么说明有共同的节点,时间复杂度为O(L1+L2),但是同时要附加O(L1)的存储空间。解法3:转化为另一已知问题由于2个链表都没有环,我们可以把第二个链表接在第一个链表后面,如果得到的链表有环,则说明2个链表相交。这样,我们就把问题转换为判断一个链表是否有环。那么“两个无环单向链表”画出来只可能是2 阅读全文

转:trie树--详解

2013-09-04 22:04 by youxin, 482 阅读, 收藏, 编辑
摘要: 前几天学习了并查集和trie树,这里总结一下trie。 本文讨论一棵最简单的trie树,基于英文26个字母组成的字符串,讨论插入字符串、判断前缀是否存在、查找字符串等基本操作;至于trie树的删除单个节点实在是少见,故在此不做详解。Trie原理Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。Trie性质好多人说trie的根节点不包含任何字符信息,我所习惯的trie根节点却是包含信息的,而且认为这样也方便,下面说一下它的性质 (基于本文所讨论的简单trie树)1.字符的种数决定每个节点的出度,即branch数组(空间换时间思想)2.branch数组的 阅读全文

算法导论:用2个栈实现一个队列,用2个队列实现一个栈

2013-09-03 09:59 by youxin, 941 阅读, 收藏, 编辑
摘要: 用2个栈实现一个队列:转的一篇文章:大多数人的思路是:始终维护s1作为存储空间,以s2作为临时缓冲区。入队时,将元素压入s1。出队时,将s1的元素逐个“倒入”(弹出并压入)s2,将s2的顶元素弹出作为出队元素,之后再将s2剩下的元素逐个“倒回”s1。见下面示意图:上述思路,可行性毋庸置疑。但有一个细... 阅读全文

面试题:递归颠倒栈 与栈排序

2013-09-01 22:01 by youxin, 2198 阅读, 收藏, 编辑
摘要: 题目:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。分析:乍一看到这道题目,第一反应是把栈里的所有元素逐一pop出来,放到一个数组里,然后在数组里颠倒所有元素,最后把数组中的所有元素逐一push进入栈。这时栈也就颠倒过... 阅读全文

数据结构之后缀数组suffix array

2013-09-01 03:44 by youxin, 506 阅读, 收藏, 编辑
摘要: 在字符串处理当中,后缀树和后缀数组都是非常有力的工具,其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料。其实后缀是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现,能够实现后缀树的很多功能而时间复杂度也不太逊色,并且,它比后缀树所占用的空间小很多。可以说,在信息学竞赛中后缀数组比后缀树要更为实用。因此在本文中笔者想介绍一下后缀数组的基本概念、构造方法,以及配合后缀数组的最长公共前缀数组的构造方法,最后结合一些例子谈谈后缀数组的应用。基本定义:子串字符串 S 的子串 r[i..j] , i ≤ j ,表示 r 串中从 i 到 j 这一段,就是顺次排列 r[i],r[i+1],.. 阅读全文

链表反转(逆序)

2013-08-27 15:54 by youxin, 1023 阅读, 收藏, 编辑
摘要: 在O(1)时间内删除某个节点:http://www.cnblogs.com/youxin/p/3294152.html链表逆序(反转)可以参考以前写的:4中方式逆序输出链表:http://www.cnblogs.com/youxin/archive/2012/06/01/2531000.html)http://blog.sina.com.cn/s/blog_9599e9510101349g.htmlgoogle题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。链表结点定义如下:structListNode{intm_nKey;ListNode* m_pNext;};分析:这是一 阅读全文

队列的2种实现

2012-07-31 17:12 by youxin, 258 阅读, 收藏, 编辑
摘要: 队列一般有以下接口:queue();构造函数int empty();void put(Item);Item get();链表实现如下:#includeusing namespace std;templateclass Queue{private: struct node { Item item; node *next; node(Item x):item(x),next(0){} }; typedef node *Link; Link head,tail;public: Queue() { head=0;} b... 阅读全文

栈 的实现

2012-07-30 16:14 by youxin, 231 阅读, 收藏, 编辑
摘要: 栈有 2种实现:一种使用队列,另一种使用链表。 当栈中有n个项时,这一实现用s[0],s[1],,..s[N-1]来保存他们。下面的代码并未实现对诸如向一个满栈中压入元素(或者从一个空栈中弹出元素)这类操作的错误检测。template<class T>class Stack{private: T *s; int n;public: Stack(int maxN) { s=new T[maxN]; n=0; } int empty() const { return n==0;} void push(T t) { s[n++]... 阅读全文

图的邻接矩阵和邻接链表表示

2012-07-28 18:37 by youxin, 7980 阅读, 收藏, 编辑
摘要: 图的邻接矩阵表示: 下面的这个程序读入一组定义一个无向图的便,创建一个对应这个图的邻接矩阵。如果在图中顶点i,j或j,i之间有一条边,就把a[i][j]和a[j][i]置为1,如果不存在这样的边,则置0。#includeusing namespace std;int main(){ int N; int i,j; cin>>N; int **adj=new int*[N]; for( i=0;i>i>>j) { adj[i][j]=1; adj[j][i]=1; }}另一种图的直观表示方法是链表数组,也叫邻接表(adjace... 阅读全文

《算法导论》12章二叉排序树BST

2012-07-26 23:33 by youxin, 777 阅读, 收藏, 编辑
摘要: 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树。 它或者是一棵空树;或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二叉排序树;二叉查找树中序遍历可得到一个有序序列。定理:如果x是一颗包含n个节点的子树的根,则调用中序遍历过程的时间为O(n).(导论上有证明)。(1)查找SEARCH 在二叉查找树中查找一个给定的关键字k的过程与二分查找很类似,根据二叉查找树在的关键字存放的特征,很容易得出查找过程:首先是关键字k与树根的关键字进行比较. 阅读全文

堆和堆排序(堆实现优先级队列)

2012-07-26 20:50 by youxin, 658 阅读, 收藏, 编辑
摘要: 堆是一种特殊类型的二叉树,它具有2个性质:1.每个节点的值大于等于其每个子节点的值2该树完全平衡,最后一层的叶子都处于最左侧的位置。n个元素称为对,当且仅当它的关键字序列k1,k2,.....kn满足ki#includeusing namespace std;//元素上移操作/*数组h[]及被上移的元素下标i输出,维持堆的性质的数组h[]*/templatevoid sift_up(T h[],int i){ if(i!=1) { while(i!=1) { if(h[i]>h[i/2]) { ... 阅读全文

二叉树

2012-07-15 23:29 by youxin, 305 阅读, 收藏, 编辑
摘要: 二叉树性质如下:1 对任何一颗二叉树,如果其终端节点数为n0,度为2的节点数为n2,则n0=n2+1; 2 具有n个结点的完全二叉树的深度为floor(logn)+1 证明:假设深度为k : 2^(k-1)-1<n<=2^k-1 或 2^(k-1)<=n<2^k于是k-1<=logn<k 因为k为整数 ,所以 k=int(logn)+1;3 N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:若I为结点编号则 如果I!=1,则其父结点的编号为I/2;如果2*I<=N,则其左儿子(即左子树的根结点)的编号为2*I;若2*I>N,则无 阅读全文

二叉树四种遍历方式总结及解剖及求深度节点数及宽度

2012-06-07 22:43 by youxin, 1118 阅读, 收藏, 编辑
摘要: 花了些时间总结了二叉树四种经典遍历方式。特别是层次遍历,值得思考。 #include<stdio.h> #include<malloc.h> typedef char ElemType; typedef struct BiNode { ElemType data; struct BiNode *lc 阅读全文