拼图,就是将1-8这几个数字,通过移动后,按照顺序排列,比如下图,排列完成后成为实现的算法如下:可以把空格认为是0,每一次移动就是数字0和周围的数字做一次交换。1.比如对状态A,数字0在4个方向上尝试(有的位置不能再移动,忽略该状态)后,得到4个不同的状态A1,A2,A3,A4。那么可以有一棵树以A为根,A1,A2,A3,A4都为叶子节点。检测这4个节点是否已经满足结果,如果是,则已经找到解了。然
TF-IDF算法全称为term frequency–inverse document frequency。TF就是term frequency的缩写,意为词频。IDF则是inverse document frequency的缩写,意为逆文档频率。该算法在信息处理中通常用来抽取关键词。比如,对一个文章提取关键词作为搜索词,就可以采用TF-IDF算法。要找出一篇文章中的关键词,通常的思路就是,就是找到
某些算法逻辑,用递归很好表述,程序也很好写。理论上所有的递归都是可以转换成非递归的。如果有些场合要求不得使用递归,那就只好改成非递归了。通常改成非递归算法的思路,就是使用临时的一个栈来存放计算的临时值。下面演示2个例子。示例一:假设有如下的递归函数f(1)=3f(2)=11f(n)=4*f(n-1)-f(n-2)那么写成代码,这个递归函数就是如下:static int f(int x)
看到老外网站上有个数论的题目,证明一下,练练脑筋。 假设(2^n)-1是质数,则求证n肯定是质数。 证明如下:反证法 假设(2^n)-1是质数,但n是合数,n=a*b.(a>1,b>1,a,b都是整数) 即2^ab-1为质数。 接下来证明(2^ab)-1必定为合数. 先证明:对于任意x^n-1 (x>2,n>2),都能因式分解为(x-1)M的一个多项式,其中M为
根据阮一峰的博客 http://www.ruanyifeng.com/blog/2013/05/boyer-moore_string_search_algorithm.html 试写算法。 使用好后缀的方法比较复杂,暂未实现。 只实现了通过坏字符的方法,事实上Boyer-Moore-Horspool算法是简化版的Boyer-Moore算法,它只使用坏字符规则。 具体代码如下: clas
哈夫曼编码取决于哈夫曼树。 将要压缩的字符串,将每个字出现的频率作为依据,构造一颗哈夫曼树,频率越大的字越是靠近树的根结点,因此它的编码也就越短。因此,频率高的字用短码,频率低的字用长码。根据这样的码表可以实现压缩字符串了。 本程序采用C#实现。 基本上是演示了哈夫曼编码压缩的原理。由于是演示代码,因此不必太纠结与效率。本程序效率必定不高。 根据码表组成的二进制码,按照7位一组转成ASCI
严格二叉树,这个定义就百度上有,维基百科都没查到。 严格二叉树的定义:如果一颗二叉树的每个非终端节点都有且仅有两棵子树,则称这颗二叉树为严格二叉树。摘自百度百科。 简单的说,没有度为1的结点的二叉树,被称之为严格二叉树。如下图就是一颗严格二叉树。 下图就不是一棵严格二叉树,因为结点5,9的度数都是1. 首先证明一个问题,对于有n个叶子的严格二叉树,必定有n-1个非叶子节点。即严格二
哈夫曼树构造 1.哈夫曼树的定义 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree)。 2.哈夫曼树的构造 假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1,w2,…,wn,则哈夫曼树的
汉诺塔的计算实现是算法课程中递归部分的经典案例。算法不难,但是要实现,还是要动点脑筋的。大致描述如下: 就是要把n个盘移动到目标柱,首先得把n-1个盘移动到临时柱。 然后把把剩下的最大的盘移动到目标柱。 然后把临时柱作为起始柱,原先的起始柱作为临时柱,重复上述步骤。 如果只移动起始柱的一个盘,就直接放到目标柱即可。 —————&
所谓分治策略,就是把规模大的问题分成若干个规模小的问题来解决,最后把各自的结果再合并。 它的一般的算法设计模式如下: Divide-and-conquer(P) 1. if |P|≤n0 2. then return(ADHOc(P)) 3. 将P分解
参考自http://zh.wikipedia.org/wiki/%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%AD%90%E5%BA%8F%E5%88%97 最长公共子序列,就是找出两个序列中最长的相同序列(不必连续) 比如ABTCK和AECK的最长子序列就是ACK。 查找出最长公共子序列需要一些数学方法。 首先设想,对于两个序列 X:x1,x2,x3.
素数环就是1-n个数,按某一序列排列,使得任意相邻2个数的和为素数。 比如1-6。素数环的排列顺序如下: 1 4 3 2 5 6 1 6 5 2 3 4 那么实现的算法,同样可以使用回溯法。 回溯法的关键思想是要找到回溯的入口点。即确定什么时候继续运算下去,什么时候停止继续,尝试下一个值。 比如对于1-6这个序列,本算法的伪代码 先把环初始化,即有0,0,0,0,0,0这样一个序列
本文中的代码在文章最后提供下载链接。 关于八皇后的问题,自己百度。回溯法的概念也可以自己维基百科中查看。 回溯法无非就是遍历解空间,如果合适的话就继续,不合适的话就放弃当前节点。可以采用递归实现。八皇后问题的经典算法就是采用回溯法。网上也有许多版本的解法,但是C#版本的似乎很少。笔者在此奉献上。 此处八皇后的算法的伪代码如下: 在第row行放置皇后(row) { for 第row行的格
AVL树是基于二叉搜索树的。但是它是自动平衡的,意思是,它左子树的深度和右子树的深度差要么是0,±1。没有其他可能。这就是AVL树,这棵树长的比较对称,不会出现极端的一边倒的情况。这也就意味着AVL在创建过程中,根节点也会不断的变换。AVL树的目的就是为了解决搜索二叉搜索树的时候可能出现最坏复杂度的情况。AVL树极端情况下复杂度也就log(n)。 但是AVL树的建立有点复杂。网上查
二叉树广度优先搜索,简单的说就是按层一层一层的遍历。 主要的算法是借助一个队列。 然后从根节点先入列,再根节点出列,同时把根节点的左右孩子入列。 然后再从队列中出列下一个节点,同时把该节点的左右孩子入列。 循环这样的步骤,直到这个队列变为空。 using System; using System.Collections.Generic; usi
二叉树搜索树的概念,维基百科描述如下: 二叉查找树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树: 1.若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 2.若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 3.它的左、右子树也分别为二叉排序树。 简单的说,就是根节点比右边叶子结点大,但比左边叶子节点小。每一颗子树都如此。
对于二叉树的最大的深度,可以采用递归算法。 算法描述如下: 如果根结点为null,那么深度=0 如果根结点不是null,那么就看该当前结点的左孩子的深度和右孩子的深度 如果左孩子深度>=右孩子的深度,那么当前根结点的深度就是左孩子的深度+1. 反之则为右孩子的深度+1 对每个左孩子右孩子也是采用同样的算法。到某一节点是null的时候,才能返回0; 之前
二叉树的基础定义可自行百度。 二叉树的遍历方法,根据数据节点的先后顺序,可分成3种方式,假设一个节点的,左孩子为L,根节点为D,右孩子为R,那么访问顺序有3中。DLR先序,LDR中序,LRD后序(左和右是并列的。所以不需要有DRL之类的顺序)。 此处以DRL为例。 算法描述如下: 首先访问根结点。 然后如果有左孩子,则对于左孩子也采用DRL的遍历规则。没有就忽略。 然后如果有右孩子,则
数据结构中,链表的概念,无非是一个结构,或者类,自身中有一个Next属性或者叫任意的名字,但是类型必须也是这个节点的类型。比如下面的例子,类名叫node,其中也要有一个属性类型也是node,这样才能串接起来。如果有多个node属性的话,那可以实现双向链表,或者十字链表,树等多着结构 class node { &nb
对于全排列,比如有5个字符abcde,则有5!=120种方法. 首先分析出数学递归公式,加上对abcde这个字符串中的字符做全排列。 那么,假设abcde是一个输入参数,输出的值则是一个全排列集合。我们就可以有: f(abcde)=a+f(bcde) //注意,此处的+号不是简单的加号,而是另一个运算规则,下面会说到。 f(bcde)=b+f(cde) f(cde)=c+f(de) f
作者:July、weedge、Frankie。编程艺术室出品。 说明:本文从B树开始谈起,然后论述B+树、B*树,最后谈到R 树。其中B树、B+树及B*树部分由weedge完成,R 树部分由Frankie完成,全文最终由July统稿修订完成。 出处:http://blog.csdn.net/v_JULY_v 。 第一节、B树、B+树、B*树 1.前言: 动态查找树主要
第一数学归纳法: 一般地,证明一个与自然数n有关的命题P(n),有如下步骤: (1)证明当n取第一个值n0时命题成立。n0对于一般数列取值为0或1,但也有特殊情况; (2)假设当n=k(k≥n0,k为自然数)时命题成立,证明当n=k+1时命题也成立。 综合(1)(2),对一切自然数n(≥n0),命题P(n)都成立。 证明: 假设对于对于命题P(n)满足第
几年前曾经写过大数相乘,但也忘记怎么写了。今天重新写了一个,中心思想就是把乘法变成加法,用字符串的方式去模拟。 感觉效率很差,算1000!花了2分23秒。有很多地方可以优化,但是目前还没时间去想。 顺便记一下: 1000!= 40238726007709377354370243392300398571937486421071463254379991042993851239862902
队列可以用两种方法实现,数组或者链表。 用数组实现的称作循环队列, 用链表实现的称作链式队列。 理论上,队列的一个特征就是没有特定的容量。不管已经存在多少元素,新的元素总能入列,也可以清空。 固定长度的数组限制了这个能力,并且低效,因为元素需要朝队首方向复制。现在的语言支持对象和指针的可以通过动态列表实现队列。往一个满的队列中插入元素会导致队列溢出,往队列删除元素会导致队列下溢。 以下代
栈有2种实现方式,分别是数组实现和链表实现。 数组实现的栈称为顺序栈,在内存中是连续存放。顺序栈中存放元素的个数有限,因此入栈的时候要判断是否已满。顺序栈中各种方法的时间复杂度均为O(1),因此是高效率的数据结构,缺点是对内存利用不够灵活。 链表实现的栈为链式栈,在内存中是分散的。存放节点数目不定。更加合理的利用内存,内存开销更小。 以下算法摘自wikipedia。 http://en.w
http://blog.csdn.net/v_JULY_v
class Program { static void Main(string[] args) {
方法逻辑为: 把数组放入一个List里面,然后给出一个随机数,求余后,从list中取出该元素。放入数组中的第一个位置。 一直取,直到list中元素都被取完位置。 private void randomarray<T>(ref T[] array) { List<T> l = array.ToList<T>()
Copyright © 2005-2024 51CTO.COM 版权所有 京ICP证060544号