![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法
文章平均质量分 51
爱拍球的程序圆
保持简单,不管是生活还是程序。编程、打球、阅读,生活中有这三件事不是已经很足够了吗?
展开
-
把数组中的奇偶数划分为两组
早上起来看了一下微软面试100题系列,其中一道题是将一个数组中的奇偶数划分为两组,其中奇数在前面,偶数在后面,下面是我的做法:#include "stdafx.h"#include <iostream>using namespace std;void swap(int inputArray[],int i,int j){ int temp = inputArray[i]; i原创 2015-02-06 10:54:40 · 1277 阅读 · 0 评论 -
每日一题17:八皇后问题
八皇后问题是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。解题的思路如下:从棋盘的第一行起,先选择第一个格子作为第一个皇后的位置,然后在第二行中从第一个格子原创 2015-04-06 23:32:02 · 1146 阅读 · 0 评论 -
每日一题19:循环队列
基于数组实现的循环队列,这个比基于链表实现的稍微麻烦一点,需要浪费一个存储空间。如果全部利用,则编程将会变得更加繁琐,并且更容易出错。// LoopQueue.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>using namespace std;struct loop_queue{ int capacity;原创 2015-04-08 22:34:23 · 701 阅读 · 0 评论 -
每日一题23:查找树基本操作
距离上一篇博客已经过去了四天,“每日一题”这个标题给的压力还是挺大的,这四天一直在学习查找树,同时更进一步地接触STL,所以更新慢了。查找树的删除操作整整花了一天才学会,比较耗时,另外两个有点麻烦的地方是迭代器的前进与后退,需要画图再根据查找树的性质推理。这三个操作算得上两个题吧,整个查找树操作算得上一个题,这样想想,嗯,勉强对得起标题啦,O(∩_∩)O。好了,闲话少说,上代码,吸取了以前的教训,原创 2015-04-19 16:26:19 · 534 阅读 · 0 评论 -
每日一题18:栈
用C++写了一个栈模板,其间用了一些《Effective C++》的准则,记录在这里喽。这个类还没有做到异常安全,以后改进! Stack.h文件。#ifndef _STACK_H_#define _STACK_H_namespace MyDataStructure{ template <typename T> class Stack { private:原创 2015-04-09 08:13:55 · 616 阅读 · 0 评论 -
每日一题22:Deque与Trait
虽然之前写过一个Deque,但是那个属于C与C++混合的产品,近来在学习C++模板,所以写了一个C++版,同时第一次尝试使用Trait技术。 本来已经写好的文章,发表之后丢失了,好郁闷,没心情再写了,贴贴代码吧。这个Trait是用来决定传递参数时是使用值传递还是引用传递#ifndef _TYPE_TRAITS_H_#define _TYPE_TRAITS_H_namespace MyDataSt原创 2015-04-15 10:35:55 · 1009 阅读 · 0 评论 -
每日一题24:堆
本文记录了使用C++模板实现了堆的基本操作,对于其他一些有用操作如IncreaseKey和DecreaseKey等则没有实现,这是因为使用模板把最小堆和最大堆揉在一起,对Key的增减我还没有找到比较好的处理方式,而现在写这个堆数据结构主要是因为在Hoffman树算法需要,基本操作已经够用了。 堆是一棵完全二叉树,所谓完全二叉树就是一棵从上倒下,从左到右依次填满每一个位置的二叉树,除了最后一层节点没原创 2015-05-14 14:59:16 · 671 阅读 · 0 评论 -
每日一题27:并查集
并查集是一种支持合并于查找的结构,主要用于快速将一个集合与另一个集合合并,查找某个元素所在的集合。假设有N个元素,编号为0到N-1,那么可以构造一个同样大小的整数数组A,A中每个元素存放对应集合元素所属类的编号,查找一个元素所在的集合时,到A中检查对应下标的元素就知道了一个所属的集合。当要合并时,把涉及的元素在A中对应下标的元素设为合并后的集合标识,原创 2015-05-24 10:23:54 · 456 阅读 · 0 评论 -
每日一题29:最小生成树
最小生成树是指包含图中所有的顶点而又没有环并且所有边的权值最小的子图,由于这张图没有环,所以就是一棵树。比较流行的两种找到最小生成树的算法有Kruscal算法和Prim算法。本文在代码注释里写明算法的原理和实际计算步骤,然后贴出两种算法运行的结果示例,最后证明算法的正确性。原创 2015-05-29 08:23:03 · 919 阅读 · 3 评论 -
每日一题28:图的基本操作
本文记录了基于邻接表表示的有向有权图的基本操作。邻接表表示的图的结构就是用一个散列表存储图的节点,而每个节点后面跟着从节点出发的所有边的集合,这些边用链表连接起来,所以在这样的图中寻找一个节点发出的边是容易的,但是寻找进入一个节点的边是困难的,需要遍历所有的边。删除一条边也比较容易,删除一个节点则需要寻找与该节点相关的所有边,并将这些边也删除。#ifndef _NOWEIGHTGRAPH_H_#d原创 2015-05-28 19:14:57 · 685 阅读 · 0 评论 -
每日一题30:拓补排序
所谓拓补排序就是确定图中节点的一种顺序,使得某些在别的节点访问之前不能访问到的节点排在后面。所以该算法的核心是每一步选择一个没有入度的节点,因为没有入度意味着该节点没有前驱,得到一个节点后,就把以新得到的节点为起点的边去除,从剩下的节点重复前面的过程直到所有节点都排好序或找不到一个不具有入度的节点为止。但是实际实现中不必真的删除边,只需要记录每个顶点的入度数,删除边的操作就可以用递减相关顶原创 2015-05-29 09:04:00 · 791 阅读 · 0 评论 -
每日一题31:图的遍历
算法概述图的遍历是指访问图中每个节点一次。图的遍历方式主要有两种,一种是深度优先,即能走多远就先走多远的遍历方式,这就意味着,对于每个节点的遍历完后,下一个访问的节点应该是他的邻接点,而不是兄弟节点。另一种方式是深度优先的方式,这是一种分层遍历,对于没一个节点访问完后,就访问它的兄弟节点,而不是优先考虑邻接顶点。深度优先算法使用递归实现比较直观,而广度优先遍历则需要一个栈辅助,和分层遍历一棵二叉树的原创 2015-05-30 10:55:27 · 1031 阅读 · 0 评论 -
每日一题32:排序
排序概述排序用途广泛,比如为数据库查询结果按时间排序,最小生成树算法中对边按权重排序,背包问题中对物品按大小排序等等。排序算法有很多,本文主要记录了冒泡排序、插入排序、快速排序、选择排序、堆排序、归并排序等几种比较流行的算法。冒泡排序 //冒泡排序,对数组做n-1趟扫描,每一趟把未就位的元素中的最大的元素 //放到他正确的位置上,每一趟扫描从输入数组第一个元素开始,依次原创 2015-05-31 08:41:38 · 1152 阅读 · 8 评论 -
每日一题26:求逆序对数目与求和
求逆序对问题与解决方案原理在一个数列中,如果规定从小到大为正序,那么如果排在后面的某个元素比前面的某一个元素小,那么就称这两个数构成一个逆序对,例如,数列5,4,3,2,1中,任一个数都与它前面的数构成逆序对,这个序列中一共就有1+2+3+4=10个逆序对,数列23541中有5个逆序对,那么任给定一个数列,如何知道有多少个逆序对呢?简单的方法是将每个元素与它后面的元素比较,然后就可以累加出总的原创 2015-05-21 20:57:28 · 1370 阅读 · 0 评论 -
每日一题14:数组与链表组合方案下的Josephus问题
愚人节与自己开了个很大的玩笑,几天没写程序,今天继续!Josephus问题是说N个人围成一个圈传热土豆,先约定一个数M,当传递了M次的时候拿着土豆的人出局,然后将土豆给出局人的下一个人,游戏继续,直到最后只剩下一个人,求出局人的序列(按出局顺序排列)。 这个问题可以用数组实现,但是需要标记代表出局人的元素,并且没遍历一个元素就要检查该元素是否已被标记为出局,这样程序运行时间必然会变慢。另一种方式是原创 2015-04-04 09:38:18 · 641 阅读 · 0 评论 -
每日一题21:从0打印到具有n位整数的最大数
该题目的难点在于n可能很大,超过了整数表示的范围,所以一般有两种思路,一种是用字符串表示整数,并实现++操作符,另一种是把该题目当做排列组合来做,使用递归可以实现,下面给出使用递归实现的代码:void __print(char digit_array[], int index, int n){ if (index < 0) return; if (index == n - 1)原创 2015-04-10 23:32:34 · 587 阅读 · 0 评论 -
每日一题16:在一个数组中实现两个栈
在一个数组中实现两个栈,当数组未填满是任一个栈不能溢出。解法是将一个栈从头开始往后插入,而另一个从后往前插入,如果插入一个元素后,两个栈的top指针未相遇,则表示数组未满,栈没有溢出。#include "stdafx.h"#include <iostream>using namespace std;struct special_stack{ int capcity; int l原创 2015-04-05 10:17:49 · 756 阅读 · 0 评论 -
求一棵二叉树的高度
利用递归来求一棵树的高度,基本思想是:对于每一个非空节点,先求取其左子树的高度,然后求取其右子树的高度,最后取两子树中较高的一个加1作为以该节点为根的树的高度;对于空节点,直接返回0就可以了。求整棵树的高度只需将此思想运用到根节点上即可。struct BST_Node{ int m_value; BST_Node* left_child; BST_Node* rigth_c原创 2015-02-07 08:58:59 · 3404 阅读 · 0 评论 -
求子数组的最大和
题目要求如下: 输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。要求时间复杂度为 O(n)。 例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为 3, 10, -4, 7, 2, 因此输出为该子数组的和 18。这个问题还是来自July微软面试100题序列,我的解题思路原创 2015-02-07 15:21:24 · 595 阅读 · 0 评论 -
每日一题8:查找文本中最长的重复字串
输入一本英文书,找出其中最长的完全重复的字符串。一本书可能有几十上百万的字符,按顺序能够组成的字符串可定比这本书包含的字符高几个数量级(考虑字符串的长度、开始取子字符串的位置变化),所以想要用暴力遍历基本上是不可能完成的,然而使用后缀数组却可以轻松解决,后缀数组是这样形成的,假设有一个字符串char * s = “abcde”,然后我们定义一个和该字符串具有同样长度的char类型的指针数组s_ptr原创 2015-03-25 08:21:21 · 739 阅读 · 0 评论 -
每日一题9:字典树(一)
百科上对于字典树的定义是:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。其结构如下: 今天,就来实现一个简单的字典树,本次实现只包含创建字典树(未考虑排序问题,如果输入的单词原创 2015-03-26 23:28:39 · 610 阅读 · 0 评论 -
每日一题10:在排序的二维数组中查找
排序的二维数组是这样的:在每一行中元素是递增的,在每一列中元素也是递增的,比如: 11 34 35 47 51 13 37 40 52 61 19 42 50 79 80 给定一个值,判断其是否在这样排序的二维数组中。 首先,先来生成测试数据,思路如下:1)先选择一种将给定输入按升序排列。2)构造一个二维数组,寻找该数组中以第一个元素为起点,确定一个最大的正方形区域(其宽要么与原数组的行或原创 2015-03-27 19:10:45 · 579 阅读 · 0 评论 -
每日一题1:查找前k个最小值
查找前k个最小值最直接的方式是遍历输入数组k遍,每次找出剩下输入中的最小值,每次查找过程中采用交换的策略,这样程序运行结束原数组的前k个数就是按顺序排列的前k个最小数,第二种思路是维护一个具有k个元素的查找树(初始化为输入数组的前k个数),对输入数组的后续每个元素a,将其与查找树的最大数b比较,如果a>=b,则什么也不做,如果a < b,则将b删除,再将a插入到查找树中,如此即可在O(n+klogn原创 2015-03-18 10:16:12 · 813 阅读 · 0 评论 -
每日一题3:判断单链表是否相交
由于单链表的特殊性,如果某一链表与另一链表相交,那么从相交的节点开始,以后两个链表的每个节点都相同,因此判断两个链表是否相交,只需判断每条链表的最后一个节点是否相同即可!#include "stdafx.h"#include <iostream>using namespace std;struct list_node{ int data; list_node* next;};原创 2015-03-20 22:20:54 · 641 阅读 · 0 评论 -
每日一题11:替换字符串中的空格
用指定的字符或字符串替换某个字符串中出现的所有空格,当用字符替换字符是,自然是很简单的,但是当使用字符串替换字符时,如果还是从前往后遍历,遇到指定字符就将其后所有字符往后移出足够空间的话,当字符串中的空格很多时,反复的移动字符会带来性能上的损失。但是如果是从后往前遍历呢?可以先遍历一次原字符串,得到字符串中空格的个数,然后就可以计算出实际需要的空间,再假设原字符串所在缓冲区有足够空间(否则新建一个缓原创 2015-03-28 08:08:42 · 1161 阅读 · 2 评论 -
每日一题2:反转英文句子
反转英文句子的意思是将句子中按顺序排好的单词的顺序颠倒过来,例子如下: 输入: wo shi zhong guo ren 输出: ren guo zhong shi wo 直观的解法是先将每个单词提取出来,然后计算每个单词反转后所的位置,最后将单词填到相应的位置上。这种方案不仅占用辅助空间,并且计算复杂。另一种方案是将整个句子看做一个字符串,先反转字符串字母的顺序(包含空格),然后再一次反转每原创 2015-03-19 10:40:01 · 1271 阅读 · 0 评论 -
每日一题4:快速排序
快速排序是目前平均性能最好的排序算法(从通用层面上考虑),其平均时间复杂度为O(nlogn).快速排序的思想很简单,首先将待排序的序列以某个元素为轴划分为两组,轴的左边元素不大于轴,右边的元素不小于轴,接下来分别对轴左边的元素(左子序列)和右边的元素(右子序列)进行同样的划分(每个子序列均不包含作为轴的元素,因为此时它已经处在了正确的位置上),这个过程不断重复下去,知道子序列元素个数为1时,那么排序原创 2015-03-21 11:08:01 · 716 阅读 · 0 评论 -
每日一题12:用数组加速递归
许多教学书上都用斐波那契数列(数列中第一二个值都是1,其它任意一个数都是其前两项之和)作为讲解递归的例子,作为教学例子,它确实十分合适,但是如果用在实际计算中,那么递归实现的斐波那契数列求值实在是太满了,其中主要的原因是重复计算实在太多,这样的递归算法不仅速度效率低下,还容易造成栈溢出。如果能够保留下已经计算过的值,但需要时直接取用而不是重复计算,那么必然会提高程序性能。 对于斐波那契数列求解使原创 2015-03-29 08:02:31 · 703 阅读 · 0 评论 -
每日一题5:单词统计
一篇文章由很多单词构成,有的时候我们想统计一下文章中单词出现的次数,怎样快速地做呢?《编程珠玑》书中提到的一种方式是使用散列表,本文实现了该方法。 为了简单,单词定义为仅由英文字母构成的,暂时忽略连字符号,所有单词由空格分开,所以先对一篇文章进行预处理://返回处理后单词总数int pre_process(const char* filename){ ifstream input原创 2015-03-22 11:54:56 · 729 阅读 · 0 评论 -
每日一题6:位图向量排序
位图向量排序有三大优点:1)速度快,复杂度为O (n);2)内存需要少;3)排序时间与输入元素数据无关,但它也有三个很严苛的限制:1)整数;2)元素值在一定范围之内(与机器内存有关)3)没有重复。它的本质是使用位数组的下标来记录元素值,而数组的值表示该元素下标是否存在,因此达到节省内存、加快速度的目标(节省内存是针对元素比较密集的情况,过于稀疏的情况未必就节省内存)。 比如说要表示包含1-5范围内原创 2015-03-23 08:24:20 · 730 阅读 · 0 评论 -
每日一题13:多项式的(基于链表实现)简单运算
多项式的每一项可以需要两个参数,即系数与指数。描述多项式的一种方式是用数组的下标表示项的指数,而用数组存储的元素表示相应项的系数。这样表示的多项式看起来很简单,但是在很多计算中却显得很不方便,这种不方便主要出现”在稀疏的“多项式中(比如x的10000次方加1),如果要输出多项式却要从头到尾扫描数组。另一个缺点是浪费了很多的空间,上面的例子中有效的数组元素仅仅只有两个。所以最好还是用链表表示,每个节原创 2015-03-30 20:45:10 · 674 阅读 · 0 评论 -
每日一题7:二分搜索
搜索最简单的方法是顺序搜索,该搜索方法可以在O(n)时间复杂度内确定是否搜索成功,并且对于搜索空间并无特殊要求,但是如果搜索空间中的元素是按顺序排列的时候,如果使用二分搜索的话,就可以将完成一次搜索的时间复杂度降到O(logn)。所谓二分搜索是指在已排序的搜索空间中每一次比较均与处于搜索空间中间的元素b比较,如果待搜索的元素a大于b,那么就在搜索空间的后半段空间中继续搜索,如果a等于b那么就表示搜索原创 2015-03-24 08:48:19 · 676 阅读 · 0 评论 -
每日一题15:双端队列与自调整表
双端队列是一种插入和删除可以既可以在表头也可以表尾进行的一种数据结构,四种基本操作分别为: push:在表头插入 pop:在表头删除 insert:在表尾插入 eject:在表尾删除 每一种操作的复杂度都为O(1)。通过组合不同插入和删除,双端队列可以作为栈使用,也可以作为队列使用:#include "stdafx.h"#include <iostream>using namespace原创 2015-04-05 09:34:35 · 1000 阅读 · 0 评论 -
每日一题25:Hoffman树
Hoffman树是由David A. Hoffman于1952年在MIT攻读博士学位期间发表的论文《A Method for the Construction of Minimum-Redundancy Codes》中提出的,它的目的寻找一种利用最少量的编码方法表示信息。Hoffman使用自底向上的方法构建了一棵满足要求的树,用这棵树进行的编码叫做Hoffman编码。 用一个节点表示一条信息,每条原创 2015-05-19 15:45:27 · 698 阅读 · 0 评论