数据结构与算法
文章平均质量分 90
Sunshine_top
安安静静、认认真真完成自己的事情
展开
-
红黑树操作及实现
红黑树性质 红黑树是广泛应用的平衡二叉搜索树之一(另外一种常见的平衡二叉搜索树是AVL树)。它是SGI STL唯一实现的一种搜索树;是关联容器的底部机制。 和AVL树所实现的平衡机制不同,但是同样适用了单旋转和双旋转操作修正树以保证平衡。 红黑树的性质: 1. 每个节点都被着上黑色或者红色。原创 2015-01-05 21:27:16 · 1938 阅读 · 0 评论 -
堆的基本操作
如下的代码分别是:根据初始序列建立小根堆,堆的插入、堆的删除等操作。堆排序的实现参考文章:堆排序//heap.h#ifndef TEST_HEAP_H#define TEST_HEAP_H#include "test.h"/*这里建立的是小根堆,元素存在vector容器中,根从下标为1的元素开始*/template class BinaryHeap {publi原创 2015-07-03 14:37:50 · 1837 阅读 · 0 评论 -
动态规划:求最长公共子串/最长公共子序列
最长公共子序列和最长公共子串区别 最长公共子串(Longest Common Substring)与最长公共子序列(Longest Common Subsequence)的区别: 子串要求在原字符串中是连续的,而子序列则只需保持相对顺序一致,并不要求连续。例如X = {a, Q, 1, 1}; Y = {a, 1, 1, d, f}那么,{a, 1, 1}是X和Y的最长公共子序原创 2015-04-30 11:30:58 · 35898 阅读 · 0 评论 -
堆排序
对于小根堆来说,一般的思路是每次删除最小值,执行N次删除;每次将删除的元素拷贝到一个新的数组,那么新数组将按照从小到大的顺序排列。这里的主要问题是空间的:使用新数组,使存储空间增加了一倍。 一个技巧是:每次删除一个堆元素,堆大小会减少1。那么位于堆最后的那个空间可以用来存放刚刚被删除的元素。按照这种思路,不用额外的空间即可完成排序。 对小根堆,该方式排序完的数原创 2014-12-20 16:57:14 · 1789 阅读 · 0 评论 -
常用的字符处理函数实现:strstr strcpy strcat memcpy memmove
1、strstrstrstr函数有两个版本:const char * strstr ( const char * str1, const char * str2 ); char * strstr ( char * str1, const char * str2 );(1) 朴素的实现方式遍历两个字符串,在str1中逐个匹配str2,时间复杂度O(nm).原创 2015-07-13 08:23:50 · 1095 阅读 · 0 评论 -
leetcode难度及面试频率
http://blog.csdn.net/yutianzuijin/article/details/11477603 1Two Sum25arraysort原创 2015-08-07 15:09:20 · 1317 阅读 · 0 评论 -
hash函数的基本知识
Hash函数也称为散列表,是一种常用的数据结构。哈希表优点:可以提供快速插入和查找操作,无论有多少数据项,插入与查找只需接近常量的实际:O(1)时间级。而且编程很容易实现。哈希表的缺点:它是基于数组的,数组一旦被创建,就难以拓展;某些哈希表的填充因子(填入的元素个数/哈希表长度)过大,性能会急剧下降。 Hash函数在多个领域均有应用,而在数字签名和数据库实现时又用的最多,比如基原创 2015-04-15 15:06:43 · 6444 阅读 · 1 评论 -
一致性哈希
基本哈希知识:hash函数的基本知识 最常规的方式莫过于hash取模的方式。比如集群中可用机器适量为N,那么key值为K的的数据请求很简单的应该路由到hash(K) mod N对应的机器。的确,这种结构是简单的,也是实用的。但是在一些高速发展的web系统中,这样的解决方案仍有些缺陷。随着系统访问压力的增长,缓存系统不得不通过增加机器节点的方式提高集群的相应速度和数据承载量。增加机器意味着原创 2015-07-18 08:03:53 · 924 阅读 · 0 评论 -
归并排序及其空间复杂度的思考
对归并排序来说:如果对Merge的每个递归调用都声明一个临时数组,那么任一时刻可能会有logN个临时数组处于活动期,这对小内存机器是致命的。另一方面,如果Merge动态分配并释放最小量临时空间,那么由malloc占用的时间会很多。由于Merge位于MSort的最后一行,可以在MergeSort中建立该临时数组。因此在任一时刻只需要一个临时数组活动,而且可以使用该临时数组的任意部分;我们将使用和原创 2014-12-20 17:27:04 · 16250 阅读 · 5 评论 -
位运算的常见操作和题目
一、位运算基本操作& 与 1 & 1 = 1;1 & 0 = 0;0 & 0 = 0 只有当两个位都为1时,结果为1| 或 1 | 1 = 1;1 | 0 = 1;0 | 0 = 0 只有两个位都为0时,结果为0^ 异原创 2015-06-29 21:04:09 · 5465 阅读 · 2 评论 -
基础排序算法总结
一、冒泡排序冒泡排序的普通思路: 比较相邻的两个元素,交换元素使得小元素在前、大元素在后。 第一次排序将对n个元素进行n-1次比较,将最大的元素放到了数组的最后边; 第二次排序将剩下的n-1个元素进行n-2次比较,将第二大的数放在数组的倒数第二个位置; 依次进行该过程; 第n-1趟则所有元素原创 2015-03-17 20:06:33 · 3148 阅读 · 0 评论 -
B-树、B+树、Trie树
B-树性质:是一种多路搜索树(并不是二叉的): 1.定义任意非叶子结点最多只有M个儿子;且M>2; 2.根结点的儿子数为[2, M]; 3.除根结点以外的非叶子结点的儿子数为[M/2, M]; 4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)原创 2015-07-05 19:34:21 · 1737 阅读 · 0 评论 -
在数组中找出两个数a、b,使得a加b等于给定的c
题目:有一个整数数组array,给定整数sum,从这两个数中选取两个数a、b,使得a+b = sum。《编程之美2.12 》一、满足条件的两个数找出两个数a、b,使得a + b = sum;等价于:从数组中找一个数b使得 b = sum - a;方法一//方法一:穷举法。查找任意两个数,看其之和是否为给定数//该方法时间复杂度为O(n^2)方法二//方法二:对数组原创 2015-08-14 16:57:25 · 6534 阅读 · 0 评论 -
最小生成树算法
最小生成树的两种算法是Prim算法和Kruskal算法,前者的复杂度只跟图的边数目相关:O(n^2),后者的复杂度只跟图的顶点数目相关:O(eloge)。两个算法都依据贪心算法。Prim算法从图中任选一个顶点(下面的算法选取编号为1的顶点)作为起始顶点,然后从此顶点开始,依次将各个顶点加入这个子树中,每次加入的都是未访问过的、权值最小的边和所连接的那个顶点。题目:有原创 2015-08-15 18:34:05 · 1110 阅读 · 0 评论 -
KMP(Knuth-Morris-Pratt)算法
一、朴素匹配算法也就是暴力匹配算法。设匹配字符串的长度为n,模式串的长度为m,在最坏情况下,朴字符串匹配算法运行时间为O((n - m + 1)m)。如果m = n / 2, 那么该算法的复杂度就是Θ(n ^ 2)。由于不需要预处理,朴素字符串匹配算法运行时间即为其匹配时间。strstr()函数就可以用这个方法实现,尽管效率不高://strstr函数char *strStr(co原创 2015-06-25 15:40:08 · 4289 阅读 · 1 评论 -
二叉树遍历、插入、删除等常见操作
1.二叉查找树的创建2.二叉查找树清空3.二叉查找树查询4.查找最大值、最小值5.二叉查找树插入操作6.二叉查找树的删除操作7.分别使用非递归和递归方式(部分用多种方式)实现树的先序遍历、中序遍历和后序遍历原创 2014-12-03 17:27:55 · 15711 阅读 · 3 评论 -
bitmap对海量无重复的整数排序
现在有n个无重复的正整数(n 小于10的7次方),如果内存限制在1.5M以内,要求对着n个数进行排序。【编程珠玑第一章题目】 很显然,10的7次方个整数占用的空间为10 ^ 7 * 4字节,大约等于40M,而内存限制为1.5M,因此,无法将所有数字加载到内存,所以快速排序、堆排序等高效的排序算法就没法使用。这里可以使用bitmap方式,用1bit表示一个整数,那么,10^7个整数需原创 2015-07-19 17:20:28 · 4762 阅读 · 0 评论 -
链表的常见实现
版权所有,转载请注明出处,谢谢!http://blog.csdn.net/walkinginthewind/article/details/7393134链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,也适合考察写代码的能力。链表的操作也离不开指针,指针又很容易导致出错。综合多方面的原因,链表题目在面试中占据着很重要的地位。本文对链原创 2014-11-24 20:54:14 · 5294 阅读 · 1 评论 -
Josephus约瑟夫问题及其变种
问题由来:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。原创 2014-11-21 11:18:29 · 6693 阅读 · 0 评论 -
直接选择排序
直接选择排序和直接插入排序类似,都将数据分为有序的区域和无序的区域。所不同的是直接插入排序是将无序区的第一个元素直接插入到有序区以形成一个更大的有序区,而直接选择排序是从无序区选一个最小的元素直接放到有序区的最后。void Swap(int &a, int &b) { int tmp = a; a = b; b = tmp;}void SelectSort(int a[], int原创 2015-03-17 16:22:50 · 1817 阅读 · 1 评论 -
动态规划之钢条分割
长度i 1 2 3 4 5 6 7 8 9 10价格Pi 1 5 8 9 10 17 17 20 24 30上图分别是长度为i的钢条的价格;那么现在一根长度为n的钢条,求如何切割,使得利润最大?《算法导论》205页。如果只求最大利润的值,不需要知道分割过程,有以下两种方法:原创 2015-04-07 15:27:56 · 2223 阅读 · 0 评论 -
称砝码问题
题目描述有一组砝码,重量互不相等,分别为m1、m2、m3……mn;它们可取的最大数量分别为x1、x2、x3……xn。 现要用这些砝码去称物体的重量,问能称出多少种不同的重量。 Input测试数据第一行一个整数n(n),表示有多种不同的砝码; 第二行n个整数(中间用空格分隔),m1、m2、m3……mn,分别表示n个砝码的重量;(1) 第三行n个整数(中间用空格分隔),x1、x原创 2015-05-04 16:25:48 · 3419 阅读 · 1 评论 -
avl树的C++实现
//3avl_tree_c++.h#ifndef AVL_TREE_cplusplus_H#define AVL_TREE_cplusplus_H#include using namespace std;template class AvlTree{public: AvlTree():root(NULL) {} AvlTree(const AvlTree &rhs): r原创 2015-03-30 11:33:26 · 1551 阅读 · 0 评论 -
动态规划:计算字符串相似度
《编程之美》第223页。题目描述 许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程序。我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:1.修改一个字符(如把“a”替换为“b”); 2.增加一个字符(如把“abdd”变为“aebdd”);3.删除一个字符(如把“travelling”变为“traveling”);比原创 2015-05-05 17:09:20 · 3677 阅读 · 0 评论 -
冒泡排序的改进
通常的冒泡排序 假设按照升序排序。 设数组大小为n;比较相邻的两个数,如果第一个大于第二个,则交换两个数据;这样,第一个排序后,比较了n-1次,最大的数在数组末尾。然后n = n- 1,在n不为0情况下继续排序,否则排序完成。void bubble_sort1(int a[], int size) { int i; for (i = 0; i <原创 2015-03-17 11:32:01 · 2374 阅读 · 0 评论 -
汽水瓶
描述: 有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?原创 2015-05-04 16:44:28 · 1402 阅读 · 0 评论 -
二叉堆的插入删除等操作C++实现
有几种明显的方法实现优先队列:1. 使用简单链表在表头以O(1)执行插入操作,遍历该链表需要O(N)。另一方法是始终保持表有序,插入操作代价为O(N),deleteMin花费为O(1)。2. 使用二叉查找树。插入、删除操作平均时间均为O(logN)。实现优先队列要删除最小元素,那么将会不断在左子树中删除,会损害树的平衡,会使右子树加重。这样,在最坏情况下,左子树为空,则树相当于链表,这样其原创 2014-12-19 15:05:56 · 3144 阅读 · 0 评论 -
插入排序和希尔排序
插入排序:由N-1趟排序组成,第i趟排序保证位置0到i-1上元素是已经排好序的。在该算法代码实现中使用了可以减少元素交换次数的技巧:在for循环内,实现了数组元素移动而没有明显使用交换。位置i上的元素存储在tmp中,而位置i之前的所有更大的元素 都被向右移动一个位置;然后tmp被放置在正确的位置上。这个技巧与实现二叉堆和堆排序中所用的技巧相同(可以减少交换次数,加快速度),参考二叉堆的插入删除原创 2014-12-20 16:53:51 · 1540 阅读 · 0 评论 -
AVL树(Adelson-Velskii-Landis tree)
AVL树是一个“加上了额外平衡条件”的二叉搜索树。其平衡条件的建立时为了确保树的深度为O(longN)。AVL树要求任何节点左右子树的高度相差不超过1。插入操作:左-左插入和右-右插入需要单旋转; 左-右插入和右-左插入需要双旋转。原创 2015-03-27 10:34:31 · 1983 阅读 · 0 评论 -
m个苹果放入n个盘子
题目描述放苹果问题:把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(注:5,1,1和1,1,5是同一种分法)解题分析:设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论,当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m) 当n1、有至少一个盘子空原创 2015-05-05 17:29:40 · 11040 阅读 · 1 评论 -
字符串合并处理(二进制位的倒序)
描述: 按照指定规则对输入的字符串进行处理。详细描述:将输入的两个字符串合并。对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标意思是字符在字符串中的位置。对排训后的字符串进行操作,如果字符为‘0’——‘9’或者‘A’——‘F’或者‘a’——‘f’,则对他们所代表的16进制的数进行BIT倒序的操作,并转换为相应的大写字符。如字符原创 2015-05-04 20:28:38 · 3107 阅读 · 0 评论 -
生成k个小于n的互不相同的随机数
《编程珠玑》习题1.4:如果认真考虑了习题3,你将会面对生成小于n且没有重复的k个整数的问题。最简单的方法就是使用前k个正整数。这个极端的数据集合将不会明显的改变位图方法的运行时间,但是可能会歪曲系统排序的运行时间。如何生成位于0至n - 1之间的k个不同的随机顺序的随机整数?尽量使你的程序简短高效。如下的程序产生1-n的不重复的随机数:void swap(int *a, in原创 2015-06-16 16:20:17 · 2692 阅读 · 0 评论 -
最长递增子序列
一、题目描述描述:N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形。 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, …, K,他们的身高分别为T1, T2, …, TK,则他们的身高满足T1 Ti+1 > … > TK (1 你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩原创 2015-05-02 20:40:57 · 13723 阅读 · 0 评论 -
快速排序的几种常见实现及其性能对比
Hoare的变形版本(空穴法)快速排序算法是一种不稳定的排序算法。其时间复杂度为O(nlogn),最坏复杂度为O(n^2);快排的空间复杂度为O(logn),这个不确定正确。假设待排序的数组为a[],快速排序算法最常见的做法是将第一个元素设置为枢纽元。设置两个指针low和high,它们分别指向待排序的数组的低和高位:(1)high向左移动找小于枢纽的元素,找到后(找到的是a[high]原创 2014-12-22 19:11:54 · 11579 阅读 · 1 评论 -
n个骰子的点数
题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。方法一:递归思路:设n个骰子某次投掷点数和为s的出现次数是F(n, s),那么,F(n, s)等于n - 1个骰子投掷的点数和为s - 1、s - 2、s - 3、s -4、s - 5、s - 6时的次数的总和:F(n , s) = F(n - 1, s - 1) + F(n -原创 2015-06-26 21:21:15 · 2831 阅读 · 0 评论 -
硬币的面值组合个数
http://www.cnblogs.com/python27/archive/2013/09/05/3303721.html假设我们有8种不同面值的硬币{1,2,5,10,20,50,100,200},用这些硬币组合够成一个给定的数值n。例如n=200,那么一种可能的组合方式为 200 = 3 * 1 + 1*2 + 1*5 + 2*20 + 1 * 50 + 1 * 100. 问总转载 2015-09-19 15:37:33 · 4283 阅读 · 0 评论