- 博客(124)
- 收藏
- 关注
原创 非递归遍历二叉树
<br />//// 非递归中序遍历二叉树//void InOrder(struct Node* root){ if (root == NULL) return; struct Node *t = root; stack<struct Node*> s; while (t != NULL || !s.empty()) { while (t != NULL) { s.push(t); // 压栈 t =
2010-10-22 13:50:00
1941
原创 STL 中几个简单的数值算法实现
复习《STL源码剖析》,先把几个简单的算法自己实现一下。参数没有用迭代器,直接用整型数组。#include #include /* 应用于有序区间,判断 b 中的元素是否全部被 a 包含。默认为升序,如果为降序,改变比较符号即可*/bool includes(int* a, size_t al, int *b, size_t bl){ size_t i = 0, j = 0; while (i b[j]) return false; else if
2010-10-10 23:50:00
1984
转载 STL中的内存分配器
题记:内存管理一直是C/C++程序的红灯区。关于内存管理的话题,大致有两类侧重点,一类是内存的正确使用,例如C++中new和delete应该成对出现,用RAII技巧管理内存资源,auto_ptr等方面,很多C/C++书籍中都使用技巧的介绍。另一类是内存管理的实现,如linux内核的slab分配器,STL中的allocator实现,以及一些特定于某种对象的内存管理等。最近阅读了一些内存管理实现方面的资料和源码,整理了一下,汇编成一个系列介绍一些常用的内存管理策略。1. STL容器简介STL提供了很多泛型容器,
2010-10-10 01:12:00
2229
原创 利用归并排序求数列中逆序对个数
参考了这篇文章:http://blog.csdn.net/MapReduce/archive/2007/05/20/1618515.aspx以前自己写的归并排序比较累赘,文章中的代码更有条理,而且计算逆序对个数只需要一行代码,是否对原数列进行排序也只需要决定是否取舍一行代码。#include #include int ans;void copy(int a[], int b[], int l, int r){ int i = l; while (i
2010-10-08 01:31:00
3135
原创 POJ 2485 : 最小生成树(kruskal+并查集)
DescriptionThe island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public highways. So the traffic is difficult in Flatopia. The Flatopian government is aware of this problem. They're planning to build some highways so that it w
2010-10-08 00:38:00
2320
原创 几个集合算法
上有相应的详细算法,我这里只写出了适用于普通指针的算法,思路和书上的一样。1. 交集void set_intersection(int a[], size_t al, int b[], size_t bl){ size_t i = 0, j = 0; while (i b[j]) j++; else { printf("%d ", a[i]); i++, j++; } } printf("/n");}
2010-10-07 21:55:00
1934
原创 POJ 1258 : 最小生成树(Prim)
DescriptionFarmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He needs your help, of course. Farmer John ordered a high speed connection for his farm and is going to sha
2010-10-06 13:23:00
3280
1
原创 最小生成树算法 :Prim算法 和 Kruskal 算法
加权无向图G的生成树的代价是该生成树的所有边的代价之和。下面两个算法都采用了贪心策略。Kruskal算法描述:设T是构造的最小生成树,初始为空。每次从图中选择一条权值最小的边,如果该边不能与T中已有的边形成环。则将该边加入T。如此循环直到T中含有N-1条边为止。N为节点个数。伪代码如下:T = ∅while (T中的边少于N-1条 & E不为空){ 从E中选择一条代价最小的边e; 从E中删除e; if ( e 不会在T中形成环路 ) 将e加入T;
2010-10-05 17:30:00
3782
原创 单源最短路径 :Dijkstra 算法
Dijkstra 算法用于解决有向图的最短路径问题。算法描述如下:1. 初始化原点的距离为0,到其他任意点到原点的距离为无穷大。2. 初始化已访问节点集合为空,未访问节点集合为所有节点。3. 在未访问节点集合中找到一个到已访问节点集合距离最近的节点(第一次找到的节点为原点),将该节点加入已访问节点。4. 更新该节点的邻居节点中处于未访问状态的节点的距离。5. 重复第三步。直到所有节点都已经访问。下面是一个最基本的Dijkstra 算法的c++实现,有向图存储采用的是邻接矩阵。const int MAXN =
2010-10-05 17:09:00
2145
转载 Range Minimum Query (RMQ)
解法一:Sparse Table (ST) algorithm对2k 的长度的子数组进行动态规划。我们将使用数组M[0, N-1][0, logN]进行保存,其中M[i][j]是以i 开始,长度为 2j的子数组的最小值的索引。一旦我们预处理了这些值,让我们看看怎样使用它们去计算RMQA(i, j)。思路是选择两个能够完全覆盖区间[i..j]的块并且找到它们之间的最小值。设k = [log(j - i + 1)].。为了计算RMQA(i, j) 我们可以使用下面的公式这个算法的总的时间复杂度为 const i
2010-10-04 00:44:00
2065
原创 Trend Micro 2011 笔试题
求一个字符串的最长不重复子串长度。如 "abcdefgd"的最长不重复子串为"abcdefg",长度为7。在做题的时候没带草稿纸,导致试卷上有很多涂改,而且还忘记处理字符串结尾部分。#include #include #include using namespace std;int search(char* str, int len){ map m; if (len (str[p1], p1)); while (p2 second; if (p2
2010-10-01 14:13:00
2070
原创 KMP算法
根据matrix67博客上的思路,自己实现的kmp算法,字符串下标从0开始。#include #include const int MAXN = 1000;int P[MAXN];void pre(const char* B){ P[0] = -1; int i, j = -1; for (i = 1; i -1 && B[j+1] != B[i]) j = P[j]; if (B[j+1] == B[i]) j++; P[i] = j;
2010-09-29 16:56:00
1756
转载 C++ Traits
int * p;....int i = Foo(p); 今天看"modern c++ design"的时候发现自己竟然又把以前好不容易弄懂的Traits技术给忘记了,真是...又重新学习了一下,赶紧记下来。Traits技术可以用来获得一个 类型 的相关信息的。 首先假如有以下一个泛型的迭代器类,其中类型参数 T 为迭代器所指向的类型:template class myIterator{ ...};当我们使用myIterator时,怎样才能获知它所指向的元素的类型呢?我们可以为这个类加
2010-09-27 02:15:00
1714
翻译 placement new
#include placement new。和其他普通的new不同的是,它在括号里多了另外一个参数。比如:Widget * p = new Widget; //ordinary newpi = new (ptr) int; //placement new括号里的参数是一个指针,它指向一个内存缓冲器,placement new将在这个缓冲器上分配一个对象。Placement new的返回值是这个被构造对象的地址(比如扣号中的传递参数)。placement new主要
2010-09-27 01:42:00
1940
原创 POJ 3278 : 经典BFS
Catch That CowTime Limit: 2000MSMemory Limit: 65536KTotal Submissions: 8341Accepted: 2476DescriptionFarmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number lin
2010-09-17 01:24:00
5662
转载 linux内核sk_buff的结构分析
转载自:http://simohayha.javaeye.com/blog/556168我看的内核版本是2.6.32. 在内核中sk_buff表示一个网络数据包,它是一个双向链表,而链表头就是sk_buff_head。在老的内核里面sk_buff会有一个list域直接指向sk_buff_head也就是链表头,现在在2.6.32里面这个域已经被删除了。 而sk_buff的内存布局可以分作3个段,第一个就是sk_buff自身,第二个是linear-data buff,第三个是paged-data buff(也就
2010-09-08 01:54:00
2282
转载 微软,Google面试题 (32) —— O(1)时间删除节点
Google面试题:给定链表的头指针和一个结点指针,在O(1)时间删除该结点。解法一:将该节点的next的value复制给该节点,删除next。如果给出的节点为最后一个节点,则必须遍历链表。平均复杂度为O(1)。
2010-08-25 16:02:00
2178
转载 微软,Google面试题 (31) —— 从尾到头输出链表
题目:输入一个链表的头结点,从尾到头反过来输出每个结点的值。链表结点定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;};解法一:从头遍历链表,把每个节点的值push到一个栈中。解法二:递归思想。递归输出next节点,然后输出自己节点的value。让next为NULL,递归return。
2010-08-25 15:57:00
1985
转载 微软,Google面试题 (29) —— 调整数组顺序使奇数位于偶数前面
题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。解法一:遍历数组,遇到偶数。取出该值,然后将该值后面的元素依次向前移动一位。然后将该值放到数组的最后一位。这种方法复杂度为O(n^2)。解法二:快排思想。
2010-08-25 15:46:00
795
原创 微软,Google面试题 (28) —— 字符串的排列
题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。和http://blog.csdn.net/jiangyi711/archive/2010/08/22/5830737.aspx类似。考察递归。解法一:每层递归都有一个循环。循环做的工作是将某一段的每一个字符都交换到这段字符串的开头。当字符串长度为1时,打印。
2010-08-25 15:38:00
794
原创 微软,Google面试题 (27) —— 二元树的深度
题目:输入一棵二元树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。例如:输入二元树: 10 / / 6 14
2010-08-25 15:26:00
798
原创 微软,Google面试题 (26) —— 和为n连续正数序列
题目:输入一个正数n,输出所有和为n连续正数序列。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。解法一:开辟一个大小为n/2 + 1(n为奇数,n为偶数则大小为n/2 - 1)的数组,值从1到n。两个指针p1指向1,p2指向p1的下一个。然后循环,如果p1和p2之间的元素和小于n,p2++;大于n,p1++;等于n,则输出之后p1,p2同时后移。直到p2走完数组,循环结束。这种方法时间复杂度为O(n),空间复杂度为O(n)。解法二:常规解法,复杂
2010-08-25 15:13:00
987
2
原创 微软,Google面试题 (24) —— 栈的push、pop序列
题目:输入两个整数序列。其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序。为了简单起见,我们假设push序列的任意两个整数都是不相等的。例一:push序列为12345,pop序列为45321解法一:设计一个辅助栈。第一个pop的为4,将push序列中4之前所有元素push进栈。然后将4 push再pop。第二个为5,此时栈顶元素为3。继续遍历push序列,将5之前的所有元素push,然后将5 push再pop。下一个pop的喂3,刚好是栈顶。这样直到把所有元素都pop。例二:pu
2010-08-25 15:01:00
1251
原创 微软,Google面试题 (22) —— 跳台阶
题目:一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。求总共有多少总跳法,并分析算法的时间复杂度。解法一:就是一个Fibonacci数列的问题。1. f(1) = 1; 只有一阶台阶的时候,只有一种跳法2. f(2) = 2; 有两节台阶的时候,有两种跳法。3. f(n) = f(n-1) + f(n-2)。这个和之前的“10枪打90环”问题类似,那个问题只不过是Fibonacci数列的一个扩大。
2010-08-25 02:00:00
1026
原创 《编程之美》:整数的二进制表示中1的个数
题目:输入一个整数,求该整数的二进制表达中有多少个1。例如输入10,由于其二进制表示为1010,有两个1,因此输出2。解法一:循环移位。每次移位都与1进行与运算,如果结果为1,则该位为1。这种方法的复杂度为O(k),k为该数的二进制位数。解法二:令x = x&x-1。这个操作的目的是消除最右边的1,每消除一个1,计数器加一。当x为0,则结束统计。这种方法的复杂度取决于x的二进制表达中1的个数。
2010-08-25 01:53:00
1066
原创 微软,Google面试题 (21) —— 左旋字符串(循环移位)
题目:定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。要求时间对长度为n的字符串操作的复杂度为O(n),辅助内存为O(1)。解法一:不考虑时间和空间的限制。设移动的位数为k。则循环k次,每次移动1位。这样的空间复杂度是O(1),时间复杂度是O(n*k)。如果k小于n,则O(n^2)。解法二:最直接的方法。开辟一块大小为n的内存,将前k个字符拷贝到后k个位置。将后面的n-k个字符拷贝到新空间前n-k个位置。这
2010-08-25 01:45:00
2327
原创 《编程之美》:最长公共子序列(串)
求最长公共子串有两种情况:1, 不要求子串连续,两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是它们的最长公共子串。2, 要求子串连续。对于上面两个串来说,BD和AB是它们的最长公共子串。一,有关连续的已经写过。设定一个矩阵p,p[i][j]表示以str[i]和str[j]结尾的子串的最大公共子串的长度。所以有递推式: / 0 if ip[i,j] = p[i-1,j-1]+1
2010-08-24 17:42:00
1216
1
原创 微软,Google面试题 (19) —— 反转单向链表
题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。链表结点定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;};解法一:起始节点为p1,令p2 = p1->next, p1->next = NULL。若p2为NULL,则返回p1;若p2不为NULL,进行如下循环:令p3 = p2->next。p2->next = p1;然后再令p1 = p2; p2 = p3;直到p2为NULL,退出循环。
2010-08-24 12:55:00
1361
原创 微软,Google面试题 (18) —— 用两个栈实现一个队列
解法:有两个栈A和B。队列的appendTail操作为,将元素push进A。队列的deleteHead操作为:如果B不为空,则pop栈B的栈顶元素。如果B为空,则将A中的元素全部依次pop到B,然后pop栈B的栈顶元素。扩展问题:如何用两个队列实现一个栈。解法一:有两个队列C和D。栈的push操作为:1, 将新元素添加到C的尾端。2, 如果C中只有一个元素,则不做任何工作。如果C中有超过1个元素,那么将队列C除队尾的新元素之外的其他元素依次pop,并且添加到D的尾端。保持C中只有一个元素。栈的pop操作为:
2010-08-24 02:47:00
889
原创 微软,Google面试题 (17) —— 字符串转换成整数
要注意以下几点:一,通过一个全局变量标记传入的指针是否为NULL或者是否含有非法字符或者是否造成int溢出。二,需要判断是否以+号或者-号开头。三,在函数内部用long long保存结果,如果有溢出,则结果为0。四,最后,用static_cast强制转换成int。#include #include #include enum Status{ Valid = 0, Invalid};int status = Invalid; //
2010-08-24 02:15:00
963
原创 微软,Google面试题 (16) —— O(logn)求Fibonacci数列
题目:定义Fibonacci数列如下: / 0 n=0f(n)= 1 n=1 / f(n-1)+f(n-2) n=2输入n,用最快的方法求该数列的第n项。解法一:常规解法。用递归做。不采取任何优化。int Fibonacci(int n){ if (n == 0 || n == 1) { return n; }
2010-08-24 01:27:00
1191
原创 微软,Google面试题 (14) —— 约瑟夫环
题目:n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。解法一:序号为0到n-1,则删除的数的序号为(m-1)%n,第二次就从m%n开始。所以有:序列一:0,1,2,3,....,n-1序列二:0,1,2,3,...m-2,m,m+1,....n-1序列三:m,m+1,...n-1,0,1....m-2序列四:0, 1,2
2010-08-24 01:07:00
937
转载 微软,Google面试题 (13) —— 第一个只出现一次的字符
题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。解法一:常规解法。遍历字符串,访问到每一个字符时,检查后面有没有相同的字符。没有则输出。这种做法的时间复杂度是O(n^2)。解法二:利用hashtable。首先为建立一个256大小(ASCII字符的最大值)的hashtable。遍历一次字符串,将每个字符串出现的次数存放在hashtable之中。再遍历一次hashtable,找到第一个次数为1的。
2010-08-23 23:01:00
708
原创 微软,Google面试题 (12) —— 从上往下遍历二叉树
题目:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。例如输入 8 / / 6 10 // // 5 7 9 11输出8 6 10 5 7 9 11。解法:树是图的一种特殊的退化形式。本题就是一个广度优先遍历图的问题。首先把root放进一个队列。开始循环,当队列不为空的时候。pop并且打印队首元素。然后把对手元素的孩子节点从左到右依次push进队列。继续循环。void BSF(Node* root){
2010-08-23 22:54:00
870
原创 微软,Google面试题 (11) —— 求二叉排序树的镜像
题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。例如输入: 8 / / 6 10 // //5 7 9 11输出: 8 / / 10 6 // //11 9 7 5定义二元查找树的结点为:struct BSTreeNode // a node in the binary search tree (BST){
2010-08-23 22:34:00
1341
转载 微软,Google面试题 (10) —— 在排序数组中寻找两个数的和等于给定数
题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。解法一:常规解法。对于每一个数组元素k,寻找n-k有没有在余下的数组里面,这种方法的时间复杂度为O(n^2)。解法二:两个指针begin和end分别指向数组的头和尾。如果*begin + *end大于n,begin向后移动一位。如果小于n,en
2010-08-23 21:50:00
1912
1
原创 微软,Google面试题 (9) —— 查找链表的倒数第K个节点
题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。链表结点定义如下:struct _Node{ _Node * next; value_type v;} 解法:用两个指针p1, p2。一开始都指向链表的第一个节点。然后p1向后走k-1步使其指向正数第k个节点。这时p1,p2同时前进,当p1指向链表最后一个节点时,p2向前走了n-k,也就是正数第n-k+1个节点,同时也是倒数第n-(n-k+1)+1 = k个节点。
2010-08-23 02:46:00
1070
转载 微软,Google面试题 (8) —— 求1+2+...+n
题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。解法一:用递归,利用&&运算符的特性做。解法二:用构造函数做。class内含有一个static变量,初始化为1。一个全局变量sum初始化为0。在构造函数内部首先sum += i;然后i++。构造一个大小为n,类型类class的数组,调用构造函数n次。即可获得sum。解法三:在递归的思想上,利用c++的多态性来当做递归return的条件。还利用了连续两次!!n,将n转化
2010-08-23 02:32:00
1808
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人