算法设计
文章平均质量分 70
乞力马扎罗的雪CYF
一只不孤独的猿。
展开
-
经典算法学习——非递归遍历二叉树
我们知道二叉树是一种递归定义的数据结构,包括二叉树的创建、遍历、求树高、叶子节点个数等等。使用递归来进行以上操作非常的简便,相关实现请参考 《C语言实现二叉树的基本操作》。但是今天我们剑走偏锋,使用非递归的方式来实现树的先序、中序、后序遍历。实现代码上传至 https://github.com/chenyufeng1991/TraverseBinaryTreeNoRecursion 。(1)非递原创 2016-10-03 12:28:03 · 3274 阅读 · 0 评论 -
经典算法学习——快速排序
快速排序应该算是在面试笔试中最常用的算法了,各位面试官都非常喜欢。排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,其中的思想也是用了分治法和递归的思想。示例代码上传到:https://github.com/chenyufeng1991/QuickSort算法的基本思想是:(1)先从数列中取出一个数作为基准数(常常选第一个数);(2)分区过程,比这个数大的数放到它的右边,小原创 2016-02-03 10:55:15 · 2732 阅读 · 1 评论 -
经典算法学习——二分查找
在所有的查找算法中,二分查找是最简单一种。二分查找要求原先的序列是已经排序的,每次都是以序列中间的数字作为比较,如果小于中间的数字,那么就在序列左边继续递归查找;如果大于中间的数字,那么就在序列右边继续递归查找。直到找到该数字,或者直到序列中只有一个数字的时候都还没找到,则查找失败。查找的时间复杂度可以达到O(logN),应该说是除了数组按下标查找O(1)以外的最快的查找方式了。示例代码上传至 h原创 2016-08-06 13:47:32 · 2147 阅读 · 0 评论 -
经典算法学习——斐波那契数列
在我们学习算法的过程中,斐波那契数列肯定是会碰到的一个东西,其实我们并不是为了学习一个简单的数列,更重要的是学习他的思想——递归。个人觉得递归是解决很多算法问题最高频的方法了。递归最简单的描述就是一个函数自己调用自己,达到一个条件的时候,递归结束。比如我们在以下场景常常用递归:快速排序、归并排序、二叉树的多种遍历方法等等。对于C语言实现斐波那契数列的代码已经上传至 https://github.c原创 2016-08-06 14:34:59 · 2773 阅读 · 0 评论 -
经典算法学习——数组中出现次数超过一半的数字
首先这道算法题并不是很难,看过剑指Offer的同学都知道这是里面的一道题。在各大公司的面试中也是经常被用到的,今天我们就采用最常规的方法来实现一下。 首先有人会想到,如果能把数组排序后,那么中间的那个数字就是超过一半的那个数字了(如果存在的话)。当然排序较快的复杂度为O(nlogn).这种方法完全可以实现,但未必是最好的。 因此,面试中最常规的解法就是使用快速排序中的Par原创 2016-08-06 17:31:17 · 2321 阅读 · 0 评论 -
经典算法学习——最小的k个数
经常面试的同学可能会遇到这个问题,即输出数组中的最小的k个数。同样的,这也是剑指Offer上面的一道题。这道题最简单的思路莫过于把输入的n个整数排序,排序之后位于最前面的k个数就是最小的k个数。这样实现的复杂度为O(nlogn)。如果大家看了上一篇博客《经典算法学习——数组中出现次数超过一半的数字》后,其实会发现两道题的思路是一样的,也就是要找到一个index值,它的前面都比它小,后面的都比它大。原创 2016-08-06 20:27:24 · 2073 阅读 · 0 评论 -
经典算法学习——逆转链表
链表在数据结构中是一种非常重要的线性数据结构,也是各类面试笔试中常常涉及的问题。其中最常见的一个问题就是“输入一个链表的头结点,从尾到头反过来打印出每个节点的值”,简单说就是逆转链表。当然,有人会发现,这其实就是剑指Offer中的一道题。这道题的实现我已经上传至 https://github.com/chenyufeng1991/ReverseLinkedList_Stack 。 这道原创 2016-08-07 16:51:41 · 4982 阅读 · 0 评论 -
经典算法学习——在O(1)时间删除链表节点
这道算法题同样是剑指Offer中的一道题,题目描述为:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。其实我们知道,想要在单向链表中找到某个节点并删除它,复杂度为O(n),因为必须从头遍历才能找到它(最重要的是因为要找到它的前一个节点。)所以想要O(1)完成,必须想其他的方法。 目前重要的一个信息就是已经有一个节点指针指向当前要删除的节点。这就比较好办了。我们原创 2016-08-21 13:26:54 · 2008 阅读 · 0 评论 -
经典算法学习——链表中倒数第k个节点
这是剑指Offer中非常经典的一道题,也是在面试笔试中高频出现。题目的详细描述如下:输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,从1开始计数,即链表的尾结点是倒数第一个节点。 本题有一个非常直观的解法,就是对链表扫描两遍,第一遍用来记录链表长度为n,第二次从链表头部走(n-k+1)步后,找到的那个节点就是倒数第k个节点。这种算法的问题就是需要扫描链表两遍,显得不是原创 2016-08-21 16:30:54 · 2033 阅读 · 0 评论 -
使用正则表达式提高用户密码的复杂度和安全性
大家很多都碰到这样的情况,在注册某些网站的账号时,都要求你的密码不能全是数字或是英文。最典型的就是Apple ID,必须要求是至少有数字、大写字母 和小写字母三种形式;其他比如还有淘宝账号,至少是某几种类型的组合。这从一定程度上使密码变得复杂,同时也变得安全,使别人更难以破解。这种功能的实现一般是使用正则表达式来进行检查,对用户输入进行控制。 具体需求如下:现在要求用户注册时的密码原创 2015-07-20 14:44:16 · 7503 阅读 · 0 评论 -
使用正则表达式判断字符串是否为MAC地址
今天Boss给了一个小任务,要求给定一个字符串,判断该字符串是否是MAC地址,并用Java和正则表达式实现。于是我顺便百度了下MAC地址,并在cmd下使用getmac获取本机的MAC地址,了解了一点后,就用Java实现了。为了方便测试与输入输出,选择使用Android作为UI交互。反正都是用Java,对于这个问题,一个Java项目和Android区别不大。 首先看一个MAC地址:4原创 2015-07-16 23:25:41 · 23790 阅读 · 0 评论 -
C实现头插法和尾插法来构建单链表(不带头结点)
链表的构建其实也就是不断插入节点的过程。而节点的插入可以分为头插法和尾插法。头插法就是在头结点后插入该节点,始终把该节点作为第一个节点。尾插法就是在链表的最后一个节点处插入元素,作为最后一个节点。如果想要了解链表的概念和其他链表操作,请参考《数据结构与算法之链表》《C语言实现链表的基本操作》两篇文章。示例代码上传至 https://github.com/chenyufeng1991/HeadIn原创 2016-02-25 13:05:18 · 9051 阅读 · 1 评论 -
C语言实现单链表节点的删除(不带头结点)
对链表节点进行增删改查是最基本的操作,这篇博客将会来实现对节点的删除。其他的操作可参考《C语言实现链表的基本操作》这篇博客。删除某个节点有两个类型:(1)删除i某个位置的节点;(2)判断x值是否在链表中,若存在则删除该节点;实例代码已经上传至 https://github.com/chenyufeng1991/DeleteLinkedList 。核心代码如下://删除pos位置的节点Node原创 2016-02-25 18:21:14 · 12291 阅读 · 0 评论 -
C语言实现单链表(不带头结点)节点的插入
对链表进行增删改查是最基本的操作。我在上一篇博客《C语言实现链表节点的删除》实现了删除链表中的某个节点。这里我们要来实现在某个位置插入节点。示例代码上传至https://github.com/chenyufeng1991/InsertList 。核心代码如下:Node *InsertToPosition(Node *pNode,int pos,int x){ if (pos size原创 2016-02-25 20:57:32 · 6238 阅读 · 0 评论 -
C语言实现单链表(不带头结点)的逆序打印
我在前面几篇博客中《C语言实现链表节点的插入》《C语言实现链表节点的删除》《C实现头插法和尾插法来构建链表》《C语言实现链表的基本操作》实现了链表的很多增删改查操作。这里我们要来实现链表的逆序打印,使用C来实现。代码上传至 https://github.com/chenyufeng1991/ReverseLinkedList 。 基本算法是:(1)使用尾插法构建原链表;(2)依次遍历原原创 2016-02-26 13:17:49 · 6015 阅读 · 0 评论 -
经典算法学习——单链表(不带头结点)实现冒泡排序
我在之前一篇博客《经典算法学习——冒泡排序》中简单实现了使用数组进行冒泡排序。这篇博客我们将来实现使用链表如何排序,其实整体的思路是一样的。示例代码上传至: https://github.com/chenyufeng1991/BubbleSortLinkedList 。算法描述如下:(1)比较相邻的前后两个数据,如果前面数据大于后面的数据,就将两个数据交换;(2)这样对数组的第0个数据到N-1个数原创 2016-02-26 14:53:56 · 6287 阅读 · 8 评论 -
C语言实现双向非循环链表(不带头结点)的逆序打印
我在上一篇博客中《C语言实现双向非循环链表》实现了如何构造一个双向非循环链表,并实现了正向打印。我还在之前一篇博客《C语言实现单链表的逆序打印》中实现了单链表的逆序打印。这篇博客我们来实现对双向非循环链表进行逆序打印,实现起来非常的简单。代码已经上传至 https://github.com/chenyufeng1991/ReverseDoubleLinkedList 。核心代码如下://打印非循环原创 2016-02-27 20:55:15 · 4105 阅读 · 0 评论 -
C语言实现双向非循环链表(不带头结点)的节点插入
我在之前一篇博客中《C语言实现双向非循环链表的逆序打印》讲到了如何逆序输出一个双向非循环链表,让我们对这种链表类型有了理性的认识。今天我们要来实现的是对双向非循环链表进行节点的插入。大家可以和《C语言实现单链表节点的插入》单链表的节点插入对比着学习。代码上传至 https://github.com/chenyufeng1991/InsertDoubleLinkedList 。核心代码如下:Nod原创 2016-02-28 10:08:34 · 4102 阅读 · 1 评论 -
C语言实现双向非循环链表(不带头结点)的清空
我在之前一篇博客《C语言实现单链表的基本操作》实现了如何清空一个单链表,现在换成了双向的非循环链表,整体思路是一样的。代码上传至:https://github.com/chenyufeng1991/ClearDoubleLinkedList 。核心代码如下:Node *ClearDoubleLinkedList(Node *pNode){ if (pNode == NULL) {原创 2016-02-28 13:23:37 · 2842 阅读 · 0 评论 -
经典算法学习——合并两个有序链表
类似的,合并两个有序的数组或者链表也是剑指Offer中的经典题型。题目描述如下:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是按照递增排序的。我这里以合并链表来实现。 在这里,并不需要去创建一个新的链表,只要有三个节点指针就行,第一个节点指针Node1指向第一个链表,第二个节点指针Node2指向第二个链表,第三个节点指针Node3指向新的链表。简单的示意图如下:当下一个原创 2016-08-21 16:59:45 · 2692 阅读 · 0 评论 -
经典算法学习——第一个只出现一次的字符
这同样是剑指Offer中的很经典的一道面试题。题目描述为:在字符串中找出第一个只出现一次的字符。如输入“abaccdeff”,则输出'b'. 一开始大家就会想到最简单的方法就是每访问到一个字符的时候,与后面的每一个字符去进行比较,若没有发现相同的元素,那么该元素就是第一个只出现一次的字符。这样的复杂度为O(n^2). 显然这样的效率不高。 这道题的大方向就是一题查找算法,常见的查原创 2016-08-21 19:58:06 · 2323 阅读 · 0 评论 -
C++中字符串和数字相互转化实现
在刷一些题目的时候,总是会碰到字符串和数字进行转化的问题,今天我们就在C++中来用多种方法实现。示例代码上传至 https://github.com/chenyufeng1991/TransferStringAndInt 。(1)string -> char *// string -> char * string str3 = "chenyufeng"; const char *s原创 2016-09-28 22:45:29 · 4358 阅读 · 0 评论 -
经典算法学习——求次方函数实现
在如今很多的笔试面试中,都会出现让你实现某个函数的,并且进行优化,比如降低时间复杂度。而在手写代码中,求次方函数是很高频的考点。示例代码上传至:https://github.com/chenyufeng1991/PowerFunction。题目如下:实现 double power(double x, int n)函数,实现求x的n次方。注意,n有可能为正或者负。(1)最简单的实现,循环// 最原创 2016-09-30 11:37:50 · 4484 阅读 · 1 评论 -
经典算法学习——交换二叉树的左右子树(二叉树的翻转)
对于二叉树,我们必须熟练掌握它的各种操作,今天我们要来实现二叉树的翻转,也就是交换左右子树。具体思路不难,如果一个节点是叶子节点,则不做操作;如果一个节点只有左孩子或者右孩子,则进行交换,原来的孩子为空;如果一个节点既有左孩子和右孩子,则交换左右孩子。详细代码上传至 https://github.com/chenyufeng1991/ReverseLeftRightChild。核心代码如下://原创 2016-10-01 11:41:43 · 26982 阅读 · 2 评论 -
经典算法学习——层序遍历二叉树
我们可以用很多方式去遍历一颗二叉树,比如先序遍历,中序遍历,后序遍历,其实都是通过递归的来实现。今天我们来对二叉树进行层序遍历,层序遍历的时候需要借助另一种数据结构——队列。本篇的示例代码上传至 https://github.com/chenyufeng1991/LevelOrderBinaryTree 。 层序遍历的基本思路是,当访问到一个节点的时候,把它放入队列,然后访问该值,同时原创 2016-10-01 17:16:44 · 3987 阅读 · 0 评论 -
经典算法学习——求包含某两个字符的最小子串的长度
碰到这样一道算法题:给定一个字符串,比如: cadacacbedffffreaaawc ,然后给定两个字符为f,c ,那么最短子串的长度为5。因为子串有cbedf,freaaawc. 这篇博客考虑的比较简单,是只有两个字符的情况,我会在后续的博客中讲解如果需要包含多个字符那么应该如何处理。本篇的代码上传至 https://github.com/chenyufeng1991/MaxLengt原创 2016-10-02 10:19:17 · 3186 阅读 · 0 评论 -
经典算法学习——求二叉树节点和为sum的路径
在一棵二叉树中,有多少个叶子节点,就会有多少条从根节点到叶子节点的路径。如果给每一个节点一个data值,那么每一条路径经过的节点data加起来就为sum,现在根据给定的sum,请找出有哪些路径符合这个sum。代码上传至 https://github.com/chenyufeng1991/BinaryTreePath 。 整体思路就是递归的去检索,每当经过一个节点的时候,就把节点值放入原创 2016-10-02 12:20:55 · 4588 阅读 · 0 评论 -
经典算法学习——求二叉树叶子节点的个数
二叉树的叶子节点是既没有左子树又没有右子树的特殊的节点,使用递归我们可以方便的计算出共有多少叶子节点。代码上传至 https://github.com/chenyufeng1991/BinaryTreeLeafCount 。核心代码如下:int leafCount = 0;void LeafCountBinaryCount(Node *node){ if (node == NULL原创 2016-10-02 18:27:03 · 10684 阅读 · 1 评论 -
经典算法学习——求二叉树的高度
二叉树是一种递归定义的数据结构,我们对它做的几乎所有的操作都是递归的。求树的高度也是如此。分别求左右子树的高度,然后取较长的子树作为高度。代码上传至 https://github.com/chenyufeng1991/BinaryTreeHeight 。核心代码如下:int BinaryTreeHeight(Node *node){ int treeHeight = 0; if原创 2016-10-02 21:10:39 · 17046 阅读 · 1 评论 -
C++ STL学习——algorithm
在之前的博客中我们学习了很多STL中的模板库,包括deque,queue,stack,list等,他们都是一种数据结构,也就是说STL已经为我们实现了。今天我们来讲讲STL中比较大的一个库. 主要是一些算法的运算的实现,示例代码上传至 https://github.com/chenyufeng1991/STL_algorithm 。 在使用STL中的algorithm之前,需要导入头原创 2016-09-24 11:54:00 · 4490 阅读 · 1 评论 -
C++ STL学习——string
当我们一开始使用C语言来处理字符串的时候,会感觉非常的麻烦。C语言中缺少相应的字符串处理函数,如果想要实现某个字符串功能,只能靠我们自己来实现。但是当来到C++中,字符串的处理就会变得异常简单。今天我们就来学习一下C++中最高频的字符串处理函数。示例代码上传至:https://github.com/chenyufeng1991/CppString。 首先要引入C++中的字符串头文件:#i原创 2016-08-21 11:37:53 · 2998 阅读 · 0 评论 -
经典算法学习——打印两个链表的第一个公共节点
求链表的公共节点是一道很经典的算法题,并不是很难。我们需要知道的是,一旦两个链表有一个公共节点的话,那么这两个链表的形状就是一个“Y”型。也就是说,自公共节点之后的所有节点都是一样的。如下:其实只要看了这幅图,实现就很简单了。首先我们分别遍历两个链表,分别得出他们的长度L1,L2。然后在查找公共节点时,先在长的那个链表中走|L1-L2|步,然后两个链表同时向后进行同步遍历,每走一步时,就判断后面那原创 2016-08-21 20:24:43 · 2057 阅读 · 0 评论 -
C++ STL学习——vector
学过C++的人肯定会很熟悉STL标准模板库,STL其实就是封装了一系列的接口,供我们调用。很多函数或者算法的实现不需要我们从头开始写,大大提高我们的编程效率。这篇博客在简单介绍STL的情况下,会详细的来介绍vector的使用。 STL共有六大组件:一。容器(Container):是一种数据结构,如list,vector,deque,queue等,以模板类的方法提供,为了访问容器中的数据,可原创 2016-08-21 21:45:08 · 3996 阅读 · 0 评论 -
C++ STL学习——list
如果由我们自己来实现一个链表,会写上不少代码,包括要实现创建、删除、插入等等操作。但是如果我们用了STL,那么该模板库就为我们提供了一个双向链表list,可以让我们非常方便的实现链表操作。要使用list,首先要引入头文件 #include .相关的示例代码上传至 https://github.com/chenyufeng1991/STL_list 。(1)创建list list lis原创 2016-08-22 00:00:56 · 2494 阅读 · 0 评论 -
C++ STL学习——stack
栈是最为常用的数据结构了,很多算法都是依靠栈来实现的,比如递归。我们要手动来实现栈,显得十分繁琐和麻烦,而且复用性不好。C++ 的STL中已经帮我们封装好了栈,我们只要方便的进行调用即可。该篇博客主要介绍STL 中stack的使用,stack应该说是STL中最简单的容器了。实例代码上传至 https://github.com/chenyufeng1991/STL_stack 。(1)首先引入头文原创 2016-08-22 23:50:45 · 3079 阅读 · 0 评论 -
C++ STL学习——queue
我们在上一篇博客中《C++ STL学习——stack》简单介绍了STL 中stack这种数据结构的使用,这篇博客主要来讲一下queue队列的使用。其实queue的使用和stack一样简单。示例代码上传至 https://github.com/chenyufeng1991/STL_queue 。(1)首先要引入头文件 #include . 并使用命名空间 using namespace std原创 2016-08-23 00:08:23 · 3765 阅读 · 0 评论 -
C++ STL学习——deque
在数据结构中还有一种很常见的队列叫做双端队列,我们在上一篇博客《C++ STL学习——queue》中讲到的队列queue是一种最标准的队列,只能在尾部插入数据,在头部删除数据。而今天我们讲到的deque分别可以在两端进行插入与删除,可以说用起来更加的灵活。示例代码上传至 https://github.com/chenyufeng1991/STL_deque 。(1)创建一个deque deq原创 2016-09-07 00:05:30 · 2976 阅读 · 0 评论 -
C语言实现二叉树的基本操作
我在前面的博客中讲解了链表、栈和队列,这些数据结构其实都是线性表,并且给出了详细的实现。从今天开始,我们将要来学习树,树作为一种数据结构我们经常会用到,作为起步和基础,我们先来实现二叉树,也就是每个节点有不超过2个子节点的树。对于树的操作,最基本的创建、遍历、求树高、节点数等。代码上传至 https://github.com/chenyufeng1991/BinaryTree 。(1)节点的定义t原创 2016-03-11 21:45:03 · 27069 阅读 · 4 评论 -
C++ STL学习——heap
heap堆其实是一种比较复杂的数据结构,尤其涉及到建堆和调整堆的时候。好在在STL中已经封装了heap的一些操作,可以让我们比较方便的使用堆。比如判断堆,删除一个元素,插入一个元素,以及堆排序。示例代码上传至 https://github.com/chenyufeng1991/STL_heap 。(1)首先导入头文件.(2)这里使用数组来存储一个堆,也就是堆化数组,为了方便使用,我把数组转化为ve原创 2016-09-28 20:11:10 · 2954 阅读 · 0 评论 -
经典算法学习——冒泡排序
冒泡排序是我们学习的第一种排序算法,应该也算是最简单、最常用的排序算法了。不管怎么说,学会它是必然的。今天我们就用C语言来实现该算法。示例代码已经上传至:https://github.com/chenyufeng1991/BubbleSort算法描述如下:(1)比较相邻的前后两个数据,如果前面数据大于后面的数据,就将两个数据交换;(2)这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个原创 2016-02-03 10:32:42 · 3073 阅读 · 0 评论