c/c++
文章平均质量分 73
厚积薄发~
peiyao456
这个作者很懒,什么都没留下…
展开
-
Python中的模块学习之mock模块
学习Python也有一段时间了,然而对Python中的单元测试模块这些并不是很懂,刚好,今天有点时间,就将mock模块进行学习并整理,下边进行分享:先来看一下本文的整体框架: 为什么要使用mock? 场景模拟1:比如有A和B两个模块,A模块中有调用到B模块的方法,但是很不幸,B模块中被A模块调用的方法由于一定的原因需要被修改,然而我们又不想让影响A模块的功能测试,所以就用到了单元测试模块unit原创 2017-08-10 23:31:50 · 20765 阅读 · 7 评论 -
LZW压缩算法
1.LZW压缩适用的场景: 对于有大量重复出现的字符或者字符串,可以将重复出现的多个串用一个字符表示,并写进文件。比如可以压缩这个字符串:“TOBEORNOTTOBEORTOBEORNOT”,这个字符串中出现了大量的TO,BE,OR,NOT等等字符,我们就可以将这些重复出现的字符压缩写进文件。这里只是说明算法,并没有涉及写进文件的操作。2.压缩和解压缩的原理:(1)压缩:这原创 2017-03-07 14:46:05 · 1246 阅读 · 0 评论 -
【C++】浅析C++中的对象模型
以下代码运行环境:windows8.1 32位 VS2015(一)不含有虚函数的单一继承模型:测试代码://单一继承,无虚函数class A{public: A(int a = 0, char c = 0) :_a(a) , _c(c) {} int GetA()原创 2017-02-06 21:26:01 · 593 阅读 · 0 评论 -
【leetcode】单链表的插入排序
单链表的直接插入排序排序思想跟数组的插入排序的思想是一样的。但是这里涉及到链表的插入删除等等,一些操作,实现起来还是稍微麻烦的。链表的直接插入:情况1:当前结点的值大于上一个结点的值,不用处理,直接去处理下一个结点;情况2:当前结点的值小于第一个结点的值,将当前结点插入到链表的开始。情况3:不满足上述两种情况的情况。也就是当前结点的值大于第一个结点的值,小于上一个结点的值时原创 2017-01-04 19:43:10 · 874 阅读 · 0 评论 -
虚继承
1.菱形继承: 1>继承模型: 2>代码测试并查看内存模型#includeusing namespace std;class A{public: A(int a = 5) :_a(a) { cout<<"A的构造被调用"<<endl; } ~A() { cout<<"A被析构"<<原创 2016-12-18 14:28:58 · 795 阅读 · 0 评论 -
空间配置器(二)
提前声明:这个文章本来应该命名为空间配置器(一)的,也就是说,这篇文章应该诞生于上篇文章 之前的,然而,由于本人的原因,造成这样的失误。最近一直在读《STL源码剖析》的第2章节,在讲述空间配置器的外部接口的时候,并不是特别清楚,反倒是把两级空间配置器的底层实现细节搞得比较清晰,所以,上一篇文章先于本篇文章。这两天,仔细阅读了接口这一部分,然后加上对自己空间配置器的使用,决定再来整理此文原创 2016-12-12 21:01:45 · 644 阅读 · 0 评论 -
空间配置器(一)
1.空间配置器概述:空间配置器就是为了给要执行的作业提供内存资源或者硬盘或者其他辅助资源。c++的内存配置的基本操作是::operator new(),内存释放的基本操作是::operatordelete()。这两个函数就是调用的是c语言里的malloc()和 free()函数。所以SGI就是以malloc()和 free()来完成内存的配置与释放。在前边的简易内存池的实现的文章中原创 2016-12-09 22:23:08 · 661 阅读 · 0 评论 -
简易内存池的实现
1.内存池的引入 实际运用当中,如果我们需要申请一块空间,我们一般都会new一块空间(在c语言里会用到malloc),我们知道他们两个的共同点就是在堆上申请空间,堆上的空间会比栈上的大一些(在windows的vs环境下,栈的默认大小是1MB,但是可以自己调整),所以我们可以自己去申请自己需要的大小(当然也是有一定的限制)。如果我们频繁的去申请释放空间,就会形成各种各样的内存碎片,这样就原创 2016-12-06 12:44:31 · 1134 阅读 · 0 评论 -
判断给定的序列是否是一棵BST的后序遍历序列
给定一个序列 ,判断该序列是否是一棵二叉搜索树的后序遍历序列。比如:我们知道,后序遍历的最后一个元素就是根节点,前边比它小的都位于根的左子树上,比它大的都位于根的右子树上。所以,对于上述的序列:8是这棵二叉搜索树的根。3,7 ,6都小于8,都位于8的左子树上。 6又是左子树的根,3小于6,是左子树的左孩子,7大于6,是左子树的右孩子。11,1原创 2016-12-03 17:24:14 · 1086 阅读 · 0 评论 -
二叉树中和为给定值的路径
找到二叉树中和为给定值的路径,其实核心还是求出二叉树的路径,如果路径上的值不满足条件,则说明,这条路径不是我们需要的。【实现代码】//找和为某一值的路径templatestruct TreeNode{ T _data; TreeNode* _left; TreeNode* _right; TreeNode(const T& x = T(原创 2016-12-02 17:43:08 · 559 阅读 · 0 评论 -
图的存储以及遍历
图中的容易混淆的几个重要的概念:完全图:有n(n-1)/2条边的无向图 称为完全图。有向完全图:具有n(n-1)条边的有向图称为有向完全图。稀疏图:边数比较少的图。稠密图:边数比较多的图。连通图:在无向图中,任意的两个顶点都是有路径的。强连通图:在有向图中,任意的两个顶点都是有路径的。(即就是vi到vj有路径,vj到vi也有路径)完全图一定是连通图,但是连通图却原创 2016-12-01 17:12:01 · 1426 阅读 · 0 评论 -
排序算法(八)归并排序
归并排序是利用归并的思想将一组数据进行排序。它是一种外部排序(可以对那些在磁盘上的大数据进行排序)。下边进行图解。【代码实现】//归并排序void Merge(int* a,int begin,int mid,int end,int tmp[]){ int begin1 = begin; int end1 = mid; int begin2 =原创 2016-12-01 12:17:38 · 584 阅读 · 0 评论 -
二叉树面试题
1.求二叉树中最远的两个结点的距离:思路:对于某个结点,求出其左边的高度和右边的高度,然后加起来,最后选择最大的距离就行。核心代码如下: size_t _GetMaxDistance(Node* root,size_t& distance) { if(root == NULL) return 0; int left = _GetMa原创 2016-11-30 20:32:53 · 666 阅读 · 0 评论 -
排序算法(七)海量数据的排序问题
前边几篇文章,整理过各种各样的排序,但是那些排序都是只能在内存中进行排序,而如果给大量的数据(内存中无法容纳),要给这些数据进行排序,我们就需要借助于一种外排序----归并排序(之后的文章详细介绍)。 对于大数据的排序,我们只能讲数据存储在磁盘上,然后将存储数据的文件进行分割,将小文件中的数据拿到内存中去借助快排进行排序,最后将小文件合并为一个大文件。在这中间,小文件比较多,我将小文件原创 2016-11-27 22:19:53 · 1995 阅读 · 0 评论 -
求一棵二叉树的镜像
求一棵二叉树的镜像 二叉树的镜像就是将二叉树的左右子树都交换位置得到的一棵二叉树。所以我们可以通过递归来解决。下边给出代码实现: void _Mirror(Node* root) { if(root == NULL) return; if(root->_left == NULL && root->_right原创 2016-11-26 11:24:56 · 662 阅读 · 0 评论 -
排序算法(六)非比较排序----计数排序和基数排序
前边的几篇文章介绍的几种排序算法都是比较排序,接下来的文章将会介绍两种非比较排序。计数排序:计数排序通过哈希的方法将一组数据映射到一个数组里,最后将数组中的数依次读取,并写进原来的数组,读出的数据就是有序的。综合以上图片的分析,我们知道,保存数据信息的数组(即就是计数的count数组)的大小应该是最大数与最小数之差再加1.下边请看代码实现://计数排序void Count原创 2016-11-25 19:06:35 · 616 阅读 · 0 评论 -
【操作系统】学习笔记(三)基于时间片轮转的进程调度算法
本文主要用来分享基于时间片轮转的进程调度算法,但是在分享之前,我还是先来整理一下关于进程调度的基本理论。 调度是决定或者安排事物发展次序的策略。进程的调度就是决定哪个进程来使用处理机。操作系统的3级调度:1.作业调度,又叫高级调度。决定将外存上的哪些作业调到内存的就绪队列,等待执行。2.进程调度,又叫低级调度,决定就绪队列中的哪个进程将获得处理机。3.交换调度,又叫中级调度,为原创 2016-11-23 20:58:51 · 7394 阅读 · 0 评论 -
排序算法(五)快速排序多种版本
快速排序,就像它的名称一样,是时间复杂度比较低的一种排序算法。 我们知道,快速排序是通过分治的方法,将一个大的区间划分成小区间(找一个枢纽,将大的数放置在枢纽的右边,小的数放置在枢纽左边),然后对左右的两个小区间进行排序的过程。所以,快速排序的主要就是将区间进行划分,也就是单趟排序。单趟排序有以下的几种方法:注明:以下3种方法中的GetMidNum(),下文予以解释~1.左原创 2016-11-22 21:23:10 · 7168 阅读 · 5 评论 -
排序算法(四)选择排序及优化版本
选择排序,是通过每次选择最小的数或者最大的数,然后将它放在它应该出现的位置上。 具体实现过程:将0号下标的数据保存,在之后的数中选择一个最小的数,如果最小的数不是0号数,则将最小的数与0号下标的数进行交换;将1号下标的数进行保存,在之后的数中 选择最小的数,如果最小的数不是1号数,进行交换。以此类推。 下边给出实现代码:void SelectSort(vector<int>& v){原创 2016-11-20 13:40:24 · 5871 阅读 · 4 评论 -
排序算法(三)从直接插入排序到希尔排序
在前边的文章(排序算法系列)中,我们已经介绍过几种排序 算法:冒泡排序、选择排序、直接插入排序、堆排序。直接插入排序 和希尔排序 都是插入排序系列。下边,我们再次以图片的形式解读直接插入排序,以便更好地学习希尔排序。 这样,我们就可以理解直接插入排序了,通过图示分析,我们知道直接插入排序最好的情况,就是接近有序(比如我们要求升序,刚好序列接近升序),这时直接插入排序就是相当快 的;最坏的情况就原创 2016-11-17 17:07:09 · 748 阅读 · 0 评论 -
map和set
map和set是两个主要的关联容器。关联容器究竟是什么?它和顺序容器有什么区别? 关联容器中的元素是按照关键字来保存和访问的;顺序容器中的元素是按照它们在容器中的位置来顺序保存和访问的。 map和set的底层都是通过红黑树来实现的,即中序遍历得到的序列是关键字的升序排列。然而关联容器还会由map和set衍生出一些类型。 multimap:关键字可以重复的map; multiset:关键字可以原创 2016-11-15 13:09:44 · 861 阅读 · 0 评论 -
如何判断一棵二叉树是否是完全二叉树
初次学习二叉树这种数据结构的时候,我们知道,假如一棵二叉树的高度是h,对于一棵完全二叉树,它的前h-1行一定是满的,第h行可以满也可以不满(结点必须集中于最后一行的左边),如果满则是满二叉树,不满的就是完全二叉树。概念描述不是很清晰~下边画图说明吧。 那么知道这些概念之后,我们要如何判断一棵二叉树是否是完全二叉树??? 1)如果一个结点有右孩子而没有左孩子,那么这棵树一定不是完全二叉原创 2016-11-13 21:00:42 · 15016 阅读 · 0 评论 -
如何将搜索二叉树转换成有序双向链表
在前边学习了搜索二叉树之后,我们知道,搜索二叉树的中序遍历结果是一个升序序列,如果我们可以利用二叉树的中序线索化的方法将搜索二叉树进行转换。 每一次转换时,我们需要记住当前结点的上一个结点prev,让prev的right指向当前结点cur,让cur的left指向prev,然后改变prev即可。线索化完成之后,我们需要找原来搜索二叉树的最左结点,即就是转换后的双向链表的头~ 下边给原创 2016-11-13 16:51:26 · 896 阅读 · 0 评论 -
写出一个不能被继承的类
我们知道,一个类之所以可以被继承到子类,是因为该类的构造函数和析构函数都是公有的(因为构造子类的时候,一定是先要调用父类的构造函数)。如果我们将一个类的构造函数和析构函数都写成私有或者保护,那么它就不会被继承下去。看下边的代码:class B{public: static B& GetObject() { return *(new B); }privat原创 2016-11-12 16:35:02 · 802 阅读 · 0 评论 -
只能在堆(或栈)上生成对象的类
看到这样的题目,我们首先必须明白的是,哪些变量或者说是对象是在堆上,哪些不是在堆上,这个问题,在前边的文章中已经分享过,这里,再次分享~请看图~ 知道了这些之后,我们开始分析这次分享的主题~ 1.写出一个只能在堆上生成对象的类。 方法一:要想只能在堆上生成对象,也就是说,局部对象,静态对象,全局对象都不能生成,那么我们可以将构造函数写成私有或者保护(类外不可以直接访问的),通过new来构原创 2016-11-11 19:14:04 · 794 阅读 · 0 评论 -
大数据问题
在学习c语言阶段,大家肯定都写过这样的一个程序:求一个数的阶乘。细心的同学,可能在编码的时候,会注意这个数的情况~如果给定数据过大,阶乘的结果可能会溢出~关于比较大的数的阶乘,我们就会采取别的办法~关于具体的代码,之后的文章将会为大家分享~ 再如,学习堆的时候,我们遇到这样的问题:N个数据中求取最大的前K个数,如果N不是很大,我们可以采取快排,然后选取的办法来解决~如果N很大,可以选择分组或者建堆原创 2016-11-10 12:58:35 · 645 阅读 · 0 评论 -
【数据结构】布隆过滤器
1.布隆过滤器的引入: 我们知道,在海量整形数中查找一个数字是采用位图来完成的;如果要在海量的字符串中查找一个字符串是否在其中,位图就是无法解决的,所以引入了布隆过滤器。2.布隆过滤器的概述: 布隆过滤器是由布隆这个人提出的,它是由一系列的二进制向量和一些映射函数来实现的,它主要用于检索一个字符串是否在一个集合中,并且空间效率和查询时间都是远远超过一般的算法,还可以表示全集,其原创 2016-11-08 22:25:00 · 709 阅读 · 0 评论 -
【面试题】给40亿个无符号不重复且没排过序的数,查找一个数是否在这40亿个数之中
看到这样一道面试题,我们不由的想到前边学习过的哈希表,哈希表查找效率高,唯独就是 空间浪费有点大。而在这道题目之中,40亿个无符号数(表明最高位表示大小),几乎涵盖了整形里的所有的数(总共42亿9千多)。而42亿9千多的数全部放到内存大约需要4G*4 = 16G,加上操作系统,各种运行软件,我们普通的计算机是无法运行这42亿数字的,除非超级计算机。所以,按照将每个数字都占用一个整形空间的方式导入内存原创 2016-11-07 11:24:11 · 1921 阅读 · 0 评论 -
【数据结构】哈希表
哈希表(散列表),是通过关键字key而直接访问在内存存储位置的一种数据结构,它就是 以空间换取时间。通过多开辟几个空间,来实现查找的高效率。 对于哈希表,我们并不是很陌生:在c语言学习阶段,给定一个字符串,查找第一个只出现过一次的字符;在数据结构 矩阵的高效转置方法中,计算原矩阵中每一列中有效数字的个数;在文件压缩项目(之后给出分析总结)中,计算中文件中各个字符出现的次数。 对于构造哈希表,有以原创 2016-11-04 20:37:32 · 1067 阅读 · 0 评论 -
浅析红黑树
红黑树是一棵二叉搜索树,只是它在以前的二叉树的基础上对每个结点增加了一个特性:颜色特性,或为红色或为黑色。红黑树通过保证最长路径不超过最短路径的两倍来保证近似平衡。 红黑树是满足以下特点: 1)每个节点不是红色就是黑色; 2)根节点是黑色的; 3)如果一个结点是红色,它要么没有子节点,要么子节点是黑色。(不能由连续 的红色结点) 4)对于每一个结点,从该节点原创 2016-11-02 19:52:22 · 791 阅读 · 0 评论 -
【数据结构】AVL树
AVL树,是一棵平衡搜索二叉树,既满足搜索树的性质(见二叉搜索树的文章,链接:二叉搜索树),又满足平衡树的性质(左右子树的高度差不大于2)。在二叉搜索树中,我们知道要插入一个元素,必须将他插到合适的位置,但是在AVL树中,不仅要插入到合适的位置,还要保证插入该元素之后这棵树是平衡搜索二叉树。关于如何调整一棵二叉树为平衡二叉树,这里就涉及到四种旋转:左单旋,右单旋,左右双旋,右左原创 2016-10-26 22:42:37 · 701 阅读 · 1 评论 -
排序算法(二)之堆排序
继前边的《排序算法(一)》之后,排序算法(二)就要诞生啦!!这篇文章主要来分析堆排序。在上篇文章《堆&优先级队列》中,我们分析了建堆,插入元素,删除元素的时间复杂度。这里复习一次。建堆:O(N*lgN)插入:O(lgN)删除:O(lgN)也分析了为什么优先级队列的底层要用堆!!如果上篇关于堆的文章看懂之后,下边的堆排序就比较好写了。我们知道堆的特点是:第一个元素要么是最大值原创 2016-10-12 12:39:33 · 885 阅读 · 0 评论 -
【数据结构】二叉搜索树
二叉搜索树,又叫二叉排序树,二叉查找树。它有以下特点:左子树的值小于根节点的值,右子树的值大于根节点;二叉搜索树中序遍历的结果就是一个升序序列。当然,空树也是一个二叉搜索树。全局满足二叉搜索树的性质,局部也应该满足。既然有以上性质,那么二叉树的查找是相当方便的,当然插入和删除,复杂度也会明显降低。原创 2016-10-23 12:26:17 · 793 阅读 · 0 评论 -
【数据结构】堆&优先级队列
说实话,之前看数据结构的时候,并没有更多的关注到堆,直到现在......堆数据结构是一种数组现象,可以看成是一种完全二叉树。堆的分类;最大堆:每个父节点都大于其孩子结点。最小堆:每个父节点都小于其孩子结点。注意注意:区分与二叉排序树的区别!!!堆也有很多应用,比如优先级队列,堆排序等等。再多的应用,都是先需要有堆。堆的底层是一个数组,了解STL之后可以将底层写成vect原创 2016-10-11 15:04:52 · 868 阅读 · 0 评论 -
迭代器失效问题(一)
迭代器失效问题:不光vector中有迭代器失效问题,其实list中也有。list仅有指向被删除元素的迭代器失效。 下边给出一段代码:int main(){ vector array; array.push_back(1); array.push_back(3); array.push_back(3); array.push_back(5); vector:原创 2016-10-07 17:25:02 · 709 阅读 · 0 评论 -
【数据结构】栈面试题---以O(1)时间复杂度求最小值
假设给出一组数字,我们需要在O(1)时间复杂度内完成对这组数字最小值的求解。题目具体描述:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小值元素的min函数。在该栈中,调用min,push和push的时间复杂度都是O(1).下边给出两种方法:方法一:采用辅助栈实现实现过程描述:辅助栈专门用来存储当前数据栈中的元素的最小值。当数据栈中push进第一个元素,该元素也得进辅原创 2016-10-06 14:38:19 · 1926 阅读 · 1 评论 -
二叉树的线索化(一)
本篇文章主要整理二叉树的先序和中序线索化,以及对线索树的两种遍历。线索化的引入:对于有n个节点的二叉树中,就会有n+1个空指针,导致空间的浪费。推导:对于任何一棵二叉树,叶子节点也就是度为0的节点数为n0,度为2的节点数为n2,则有n0 = n2+1。(总结点数为n)n0+n1+n2 = nn2+1 = n0.两等式联立:2*n0+n1 = n+1.所以我们引入了原创 2016-10-04 22:19:22 · 829 阅读 · 0 评论 -
【数据结构】栈面试题--一个数组实现两个栈
一个数组实现两个栈,有以下几种方法:1.数组的奇数位置存储一个栈的元素,偶数位置存储另一个栈的元素;2.两个栈分别从数组的中间向两头增长;3.两个栈分别从数组的两头开始增长。从图片中我们都可以看出,前边两种方法再一定的情况下会造成空间的浪费,所以我们采用第三种方式完成。下边给出代码实现:#includeusing namespace std;#include原创 2016-10-03 20:17:37 · 1540 阅读 · 0 评论 -
剑指offer---不使用循环条件判断等实现求和
题目描述:求1+2+3+....+n,要求不使用乘除法,for,while,if,else,switch,case等关键字及三目表达式。题目分析:由于不能使用条件判断的关键字,所以,一般的递归也是不允许的,因为通过条件判断来确定递归是否结束。但是下边的方法有模仿递归来实现求和。方法一:构造函数由于静态成员是属于类而不属于对象,根据这一特性,来实现求和。下边给出代码:cl原创 2016-10-02 16:24:06 · 754 阅读 · 0 评论 -
【数据结构】非递归遍历二叉树
由于递归时通过栈来实现的,虽然递归代码有时候看起来比较简单,然后递归太深就会造成栈溢出。所以我们可以通过栈来实现二叉树的非递归遍历。下边看解析:【先序遍历】下边看实现代码:void PreOrderTraverseNonR() { stack s; Node* cur = _root; if (cur == NULL) return; wh原创 2016-09-30 22:50:52 · 981 阅读 · 1 评论