
数据结构和算法
文章平均质量分 70
adcxf
c/c , linux ,后端开发
展开
-
随机算法
在日常工作中,经常需要使用随机算法。比如面对大量的数据, 需要从其中随机选取一些数据来做分析。 又如在得到某个分数后, 为了增加随机性, 需要在该分数的基础上, 添加一个扰动, 并使该扰动服从特定的概率分布。本文主要从这两个方面出发, 介绍一些算法, 供大家参考。首先假设我们有一个使用的随机函数float frand(), 返回值在(0, 1)上均匀分布。大多数的程序语言库提供这样的函数。 在其他转载 2011-06-08 23:20:00 · 3600 阅读 · 0 评论 -
把二元查找树转变成排序的双向链表
程序员面试题精选(01)-把二元查找树转变成排序的双向链表 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。 比如将二元查找树 10 / /转载 2008-09-27 20:44:00 · 1063 阅读 · 0 评论 -
最长公共子序列实现
一个给定序列的子序列是在该序列中删去若干元素后得到的序列。给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。最长公共子序列就是求给定两个序列的一个最长公共子序列。动态规划可以有效的解决此问题。给定两个序列X = { x1 , x2 , ... , xm }Y = { y1 , y2 , ... , yn }求X和Y的一个最长公共子序列举例X =原创 2008-08-08 10:21:00 · 1556 阅读 · 0 评论 -
数据结构小结
数据结构和算法到底有什么用?数据结构是对在计算机内存中(有时在磁盘中)的数据的一种安排。数据结构包括数组、链表、栈、二叉树、哈希表等等。算法对这些结构中的数据进行各种处理。例如,查找一条特殊的数据项或对数据进行排序。掌握这些知识以后可以解决哪些问题呢?现实世界数据存储程序员的工具建模数据结构的特性:数组:优点是插入快,如果知道下标,可以非常快地存取。缺点是查找慢,删除慢转载 2008-08-06 11:49:00 · 1419 阅读 · 0 评论 -
红黑树理论与c++实现
红黑树(Red-Black Tree)是二叉搜索树(Binary Search Tree)的一种改进。我们知道二叉搜索树在最坏的情况下可能会变成一个链表(当所有节点按从小到大的顺序依次插入后)。而红黑树在每一次插入或删除节点之后都会花O(log N)的时间来对树的结构作修改,以保持树的平衡。也就是说,红黑树的查找方法与二叉搜索树完全一样;插入和删除节点的的方法前半部分节与二叉搜索树完全一样原创 2008-08-06 09:34:00 · 3317 阅读 · 0 评论 -
红黑树C实现
// red-black tree #include #include #include #include #include ////////////////////// // supplied by user // ////////////////////// typedef int KeyType; // ty原创 2008-08-06 09:51:00 · 806 阅读 · 0 评论 -
0/1背包问题动态规划详解
动态规划是用空间换时间的一种方法的抽象。其关键是发现子问题和记录其结果。然后利用这些结果减轻运算量。比如01背包问题。/* 一个旅行者有一个最多能用M公斤的背包,现在有N件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为P1,P2,...,Pn.若每种物品只有一件求旅行者能获得最大总价值。输入格式:M,NW1,P1W2,P2......输出格式: X */因为背包最大容转载 2008-08-07 20:12:00 · 3449 阅读 · 2 评论 -
查找和排序算法简介及复杂性分析
查找和排序算法简介及复杂性分析1 跳表和散列跳表的搜索,插入,删除操作的平均时间均为O(logn),最坏情况下为O(n)。散列法是用来搜索,插入,删除记录的另一种随机方法。与跳表相比,它的插入和删除操作时间提高到O(1),但最坏情况下仍为O(n)。注:在经常将所有元素按序输出或按序号搜索元素时,跳表的执行效率将优于散列。2 搜索树跳表和散列仅能提供较好的平均性能,但最坏情况原创 2008-08-07 08:35:00 · 2110 阅读 · 0 评论 -
寻找两个单链表中第一个相同的节点
/********************************************************************** * 寻找连个链表中第一个相同的节点 * 思路:先求出两个链表的长度差diff,再将指向较长的链表的指针移动diff * 个节点,然后两个链表同时移动,并判断,若指针相同,则找到,否则,任何 * 一个链表移动到链尾,则没有共同原创 2008-08-02 22:54:00 · 1392 阅读 · 0 评论 -
Size Balanced Tree
今天上网搜索关于红黑树的资料时,发现一种新的平衡二叉树(SBT),据说各方面性能很好,先摘录在此,以后再细看。 Size Balanced Tree(SBT)是一种平衡二叉查找树。它的论文由中国广东中山纪念中学的陈启峰于2006年底完成,并在Winter Camp 2007中发表。由于SBT的拼写很容易找到中文谐音,它常被中国的OIer们戏称为“傻X树”、“Super BT”等。但它转载 2008-08-02 16:07:00 · 1354 阅读 · 0 评论 -
跳表的实现
跳表1 概念对于一个有n个元素的有序数组,用折半搜索法进行搜索所需要的时间为O(log n),而对一个有序链表进行搜索所需要的时间为O(n)。 我们可以通过对有序链表上的全部或部分节点增加额外的指针,来提高搜索性能。 通常节点结构中有一组有层次的链,0级链是包含所有元素的有序链表,1级链表是0级链的一个子集。I级链所包含的元素是i-1级链的子集。这样的结构就是跳表。增加了向原创 2008-08-02 09:19:00 · 1615 阅读 · 2 评论 -
关于哈希表大小
最近我在做一个项目,其中要用到一个数据结构――Hash Table(哈希表),以前只有理论知识,现在实却发现很不简单,所以写下来和大家共分享。我们知道,哈希表是一个固定大小的数组,数组的每个元素是一个链表(单向或双向)的头指针。如果Key一样,则在一起,如果Key不一样,则不在一起。哈希表的查询是飞快的。因为它不需要从头搜索,它利用Key的“哈希算法”直接定位,查找非常快,各种数据库中的转载 2008-07-26 16:43:00 · 3745 阅读 · 0 评论 -
洗牌算法
洗牌即产生指定数据的随机序列。在网上找了半天大体有两种做法1、 思路:将54个数依次放到随机的位置。关键是每次找一个随机的位置。下面是找这个随机位置的算法: 1、用一个Bool型数组记录各个位置是否已经放置了数,如果放置则置true,没有则为false。在算法开始时数组初始化为false。2、每次产生一个0~53的随机数,看这个位置是否已经放置了数,如果已经放置了,转载 2008-07-26 10:19:00 · 550 阅读 · 0 评论 -
设计包含min函数的栈
程序员面试题精选(02)-设计包含min函数的栈题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。 分析:这是去年google的一道面试题。我看到这道题目时,第一反应就是每次push一个新元素时,将栈里所有逆序元素排序。这样栈顶元素将是最小元素。但由于不能保证最后push进栈的元素最先出栈,这种思路设计的数据结构已经不转载 2008-09-28 13:33:00 · 2565 阅读 · 4 评论 -
求 1/1 + 1/2 + 2/3 + 3/5 + 5/8 .... 前 n 项之和!
/* 求 1/1 + 1/2 + 2/3 + 3/5 + 5/8 .... 前 n 项之和! */#include using namespace std;/* 迭代算法 */double sumOfDouble(int n){ int x = 1; int y = 1; double sum = 0; for (int i原创 2008-09-28 11:08:00 · 5020 阅读 · 0 评论 -
递归算法常见用例
1. 递归逆序打印字符串void reverse(char *s){ if(*s != ?) { reverse(++s); putchar(*(s-1)); // 巧妙的利用栈的先进后出的特点 }}2. 递归方式将链表逆序// p 为指向非空单链表中第一个结点的指针,本算法逆转链表并返回逆转后的头指针。基本思路是:如果链表中只有一个结点,则空转载 2009-03-13 23:04:00 · 1413 阅读 · 0 评论 -
求二元查找树的镜像
程序员面试题精选(11)-求二元查找树的镜像题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。 例如输入: 8 / / 6 10// //5 7 9 11输出: 8 / / 10 6// //11 9 7 5定义转载 2008-10-12 23:57:00 · 1125 阅读 · 0 评论 -
在排序数组中查找和为给定值的两个数字
程序员面试题精选(10)-在排序数组中查找和为给定值的两个数字题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。分析:如果我们不考虑时间复杂度,最简单想法的莫过去先在数组中固定一个数转载 2008-10-12 23:58:00 · 1123 阅读 · 0 评论 -
获取第一个只出现一次的字符
程序员面试题精选(13)-第一个只出现一次的字符题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。 分析:这道题是2006年google的一道笔试题。看到这道题时,最直观的想法是从头开始扫描这个字符串中的每个字符。当访问到某字符时拿这个字符和后面的每个字符相比较,如果在后面没有发现重复的字符,则该字符就是只出现一次的字符。如果字符串有n个字符,每个字符可能与后面的转载 2008-10-12 23:53:00 · 1233 阅读 · 0 评论 -
查找链表中倒数第k个结点
程序员面试题精选(09)-查找链表中倒数第k个结点题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。链表结点定义如下: struct ListNode{ int m_nKey; ListNode* m_pNext;};分析:为了得到倒数第k个结点,很自然的想法是先走到链表的尾端,再从尾端回溯k步。可是输入的是单向链表,只有从前往转载 2008-10-09 09:14:00 · 1643 阅读 · 0 评论 -
求1+2+...+n(很多限制条件)
题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。分析:这道题没有多少实际意义,因为在软件开发中不会有这么变态的限制。但这道题却能有效地考查发散思维能力,而发散思维能力能反映出对编程相关技术理解的深刻程度。通常求1+2+…+n除了用公式n(n+1)/2之外,无外乎循环和递归两种思路。由于已经明确限制for和转载 2008-10-09 08:46:00 · 1222 阅读 · 1 评论 -
判断整数序列是不是二元查找树的后序遍历结果
程序员面试题精选(06)-判断整数序列是不是二元查找树的后序遍历结果 题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。如果是返回true,否则返回false。 例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果: 8 / / 6 10 / / / / 5 7 9 11因此返回t转载 2008-10-05 16:46:00 · 1028 阅读 · 0 评论 -
翻转句子中单词的顺序
程序员面试题精选(07)-翻转句子中单词的顺序题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。例如输入“I am a student.”,则输出“student. a am I”。分析:由于编写字符串相关代码能够反映程序员的编程能力和编程习惯,与字符串相关的问题一直是程序员笔试、面试题的热门题目。本原创 2008-10-06 22:59:00 · 1502 阅读 · 0 评论 -
查找最小的k个元素
题目:输入n个整数,输出其中最小的k个。例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。分析:这道题最简单的思路莫过于把输入的n个整数排序,这样排在最前面的k个数就是最小的k个数。只是这种思路的时间复杂度为O(nlogn)。我们试着寻找更快的解决思路。我们可以开辟一个长度为k的数组。每次从输入的n个整数中读入一个数。如果数组中已经插入的元素少于k个,则将读入转载 2008-10-04 21:39:00 · 1774 阅读 · 0 评论 -
在二叉树中找出和为某一值的所有路径
程序员面试题精选(04)-在二元树中找出和为某一值的所有路径题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。例如输入整数22和如下二元树 10 /转载 2008-10-02 21:33:00 · 3144 阅读 · 1 评论 -
求子数组的最大和
程序员面试题精选(03)-求子数组的最大和题目:输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18。分析:本题最初为2005年浙江大学计算机系的考研题转载 2008-09-29 22:16:00 · 1687 阅读 · 0 评论 -
图的邻接矩阵实现(包括PRIM和DIJKSTRA算法)
#ifndef _GRAPH_H_#define _GRAPH_H_#include #include #define INFINITE 0XFF00using namespace std;class AdjacencyWDiGraph{public: AdjacencyWDiGraph(int _n, int noEdge, bool d = tr原创 2008-07-26 08:57:00 · 1120 阅读 · 0 评论 -
学习STL map, STL set之数据结构基础
学习STL map, STL set之数据结构基础作者: winter 摘要:本文列出几个基本的STL map和STL set的问题,通过解答这些问题讲解了STL关联容器内部的数据结构,最后提出了关于UNIX/LINUX自带平衡二叉树库函数和map, set选择问题,并分析了map, set的优势之处。对于希望深入学习STL和希望了解STL map等关联容器底层数据结构的朋友转载 2008-07-26 15:24:00 · 619 阅读 · 0 评论 -
希尔排序
shell排序是对插入排序的一个改装,它每次排序把序列的元素按照某个增量分成几个子序列,对这几个子序列进行插入排序,然后不断的缩小增量扩大每个子序列的元素数量,直到增量为一的时候子序列就和原先的待排列序列一样了,此时只需要做少量的比较和移动就可以完成对序列的排序了./**//* shell sort algorithm *//**//* 开始增量为数组长度的一半,然后一次减少一半,直到为1原创 2008-03-25 17:03:00 · 566 阅读 · 0 评论 -
判断数是有符号还是无符号
#includestdio.h>int main()...{ //unsigned int a = 100; //待判断数 int a = 100; int b = -1; //参照数 if(a0) ...{ printf("有符号数"); } else转载 2008-03-23 21:56:00 · 1146 阅读 · 1 评论 -
链表的翻转实现
/**//************************************************************* * FileName: reverseLink.cpp * Description: implemention for the reverse of a link * Author: Cui Xiaofeng * Date: 2008/03/22*****原创 2008-03-22 19:57:00 · 598 阅读 · 0 评论 -
回溯法实现
一、回溯法:回溯法是一个既带有系统性又带有跳跃性的的搜索算法。它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先的策略进行搜索。回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都转载 2008-03-20 21:45:00 · 1711 阅读 · 2 评论 -
回溯法介绍
回溯法有时会遇到这样一类题目,它的问题可以分解,但是又不能得出明确的动态规划或是递归解法,此时可以考虑用回溯法解决此类问题。回溯法的优点 在于其程序结构明确,可读性强,易于理解,而且通过对问题的分析可以大大提高运行效率。但是,对于可以得出明显的递推公式迭代求解的问题,还是不要用回溯 法,因为它花费的时间比较长。回溯法的基本思想对于用回溯法求解的问题,首先要将问题进行适当的转化,得出状态空间树。 这转载 2008-03-20 21:08:00 · 10662 阅读 · 5 评论 -
快速排序
快速排序的主要思想就是:将待排序数组以某一个元素为阈值分为两个子列,一个子列包含所有比改阈值小的元素,另一个子列反之。这样只要将这两个子列排好序,整个数组也就排好序了。这里有一个关键的子过程就是划分的过程Partition,一般可以选择数组中任意的元素作为划分阈值,这里选择的是数组中最左端的元素。 Partition使用了二分查找类似的思想:使用两个索引器从数组的两端进行遍历,左原创 2008-03-20 19:16:00 · 745 阅读 · 0 评论 -
堆排序
堆的定义: n个关键字序列Kl,K2,…,Kn称为堆,当且仅当该序列满足如下性质(简称为堆性质): (1) ki≤K2i且ki≤K2i+1 或(2)Ki≥K2i且ki≥K2i+1(1≤i≤) 若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存原创 2008-03-22 15:10:00 · 651 阅读 · 0 评论 -
KMP算法的实现
KMP算法是一种用于字符串匹配的算法,这个算法的高效之处在于当在某个位置匹配不成功的时候可以根据之前的匹配结果从模式字符串的另一个位置开始,而不必从头开始匹配字符串.因此这个算法的关键在于,当某个位置的匹配不成功的时候,应该从模式字符串的哪一个位置开始新的比较.假设这个值存放在一个next数组中,其中next数组中的元素满足这个条件:next[j] = k,表示的是当模式字符串中的第j + 1个(转载 2008-03-19 19:59:00 · 766 阅读 · 1 评论 -
求两个数的最大公约数和最小公倍数
/**//************************************************************ * FileName: gcd-lcm.cpp * Description: 求得两个数的最大公约数和最小公倍数 * Author: Cui Xiaofeng * Date: 2008/3/15原创 2008-03-15 10:04:00 · 816 阅读 · 1 评论 -
基本排序算法(选择,冒泡,一般插入,二分插入)源码
#include cstdlib>#include iostream>#include cassert>using namespace std;/**//* output array elements */template class T>void Print(const T *in, int n)...{ for (int i = 0; i n; i++) ...{原创 2008-03-14 12:29:00 · 651 阅读 · 0 评论 -
二叉查找树实现
#ifndef BSTREE_H#define BSTREE_H#include "binaryTree.h"template class BSTree:public BinaryTree { public: BSTree(BinaryTreeNode *root=NULL):BinaryTree(root) { } bool search(const K k); BST原创 2008-02-27 23:30:00 · 468 阅读 · 0 评论 -
AVL Tree implemention
头文件:#ifndef AVLTREE_H#define AVLTREE_Htemplate class AVLTree;template class AVLTreeNode { public: AVLTreeNode(const T k, AVLTreeNode *l = NULL, AVLTreeNode *r = NULL, int b = 0):/ key(k), left原创 2008-02-27 23:27:00 · 624 阅读 · 0 评论