C/C++学习
C、C++相关知识及数据结构
Zhao.x
这个作者很懒,什么都没留下…
展开
-
删除小写字母字符串中重复字符
删除小写字母字符串中重复元素原创 2017-08-06 22:07:36 · 930 阅读 · 0 评论 -
时间复杂度为O(n)的排序
对数组a进行排序,要求时间复杂度为O(N) 以空间换时间,新建一个数组b,这里假设arr中最大的数字不超过100,b数组全部初始化为0;例如arr中有数据12,则在b中对应的下标位置+1原创 2017-08-06 09:48:13 · 1486 阅读 · 1 评论 -
将N个字符的数组,循环右移K位。时间复杂度O(N)
1.逆序排列 abcd: abcd1234 -> dcba1234;2.逆序排列 1234: dcba1234-> dcba4321;3.全部逆序 dcba4321->1234abcd。原创 2017-08-06 10:58:21 · 1392 阅读 · 0 评论 -
STL空间配置器
为什么要有空间配置器? 1.内存碎片问题(外碎片) 由于频繁分配、释放小块内存容易在堆中造成外碎片(极端情况下就是堆中空闲的内存总量满足一个请求,但是这些空闲的块都不连续,导致任何一个单独的空闲的块都无法满足这个请求)。2.频繁的分配小块内存,效率比较低。 开辟空间的时候,分配器去找一块空闲块给用户。找空闲块也是需要时间的,尤其是在外碎片比较多的情况下。原创 2017-08-02 12:54:34 · 528 阅读 · 0 评论 -
C语言模拟实现C++的继承多态
C语言模拟实现C++的继承多态原创 2017-07-31 22:53:33 · 310 阅读 · 0 评论 -
插入排序(直接插入排序、希尔排序)
直接插入排序直接插入排序是将第一个数当作有序区,其后的数据进行排序,依次插入有序区。原创 2017-07-10 10:44:22 · 279 阅读 · 0 评论 -
选择排序(直接选择排序、堆排序)
直接选择排序直接选择排序是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。我们这里直接给出选择排序的优化,一次选出两个数据。原创 2017-07-10 16:28:05 · 256 阅读 · 0 评论 -
交换排序——冒泡排序
冒泡排序第一趟冒泡将最大的数冒在最后,第二趟将次大的数冒上去,以此类推。原创 2017-07-10 17:23:07 · 205 阅读 · 0 评论 -
交换排序——快速排序
void QuickSort(int *arr, int begin, int end){ assert(arr); int div = PartSort1(arr, begin, end); if (div - 1>begin) PartSort1(arr, begin, div - 1); if (div + 1<end)原创 2017-07-11 18:38:32 · 415 阅读 · 0 评论 -
归并排序
基本思想: 它将要排序的序列分成两个长度相等的子序列,为每一个子序列进行排序,然后再将子序列合并成一个有序的序列。合并两个子序列的过程称为两路归并。原创 2017-07-13 13:38:41 · 227 阅读 · 0 评论 -
二叉树
二叉树的特点1.每个节点最多有两棵子树,即二叉树中不存在度大于2的节点(分支数最大不超过2) 2.二叉树的子树有左右之分,也就是说二叉树是有序的。二叉树相关概念节原创 2017-07-23 10:55:43 · 312 阅读 · 0 评论 -
二叉树的基本操作
二叉树的基本操作多是由递归来实现的,包括其创建、遍历等。 根据其结构,分为根、左子树、右子树来进行相应的操作。原创 2017-07-23 12:49:04 · 237 阅读 · 0 评论 -
二叉树的非递归遍历
二叉树递归遍历的时候,将其分为根、左子树、右子树三个部分。其非递归遍历,也是分为三个部分,通过数据结构“栈”的入栈出栈操作以及其先入后出的特性,实现其遍历原创 2017-07-23 12:54:30 · 395 阅读 · 0 评论 -
判断一棵树是否是平衡二叉树及其时间复杂度的优化
平衡二叉树:它是一棵空树或者左右子树的高度差绝对值不超过1,并且左右两棵子树都是平衡二叉树。要判断一棵树是否是平衡二叉树,由其定义我们很容易想到通过计算出左右两棵子树的高度及其高度差来进行判断。原创 2017-07-26 15:46:36 · 2588 阅读 · 1 评论 -
二叉树的镜像
求一棵二叉树的镜像,归根结底就是交换这棵树及其每个子树的左右节点。通过递归即可简单的实现。原创 2017-07-26 16:14:04 · 198 阅读 · 0 评论 -
判断一棵树是否是完全二叉树
这道题可以看作是层序遍历的变形。在二叉树的层序遍历中,我们借助一个数据结构队列,根据其先进先出的性质,实现层序遍历。可以定义一个flag标志位,一旦遇到空节点,标志位生效。原创 2017-07-28 15:29:28 · 355 阅读 · 0 评论 -
求二叉树中两个节点的最近公共祖先
要求考虑以下三种种情况,给出解决方案,并解决: 1:二叉树每个节点有parent(三叉链) 2:二叉树是搜索二叉树。 3:就是普通二叉树。(尽可能实现时间复杂度为O(N))原创 2017-07-28 22:21:24 · 674 阅读 · 0 评论 -
将二叉搜索树转换成一个排序的双向链表
搜索树每一棵子树的左节点都比根节点小,每一个右节点都比根节点大。 根据其特性,我们可以通过中序遍历线索化的相关变形,来改变指针指向,实现变形。原创 2017-07-30 14:07:03 · 356 阅读 · 0 评论 -
由前序遍历和中序遍历重建二叉树
由前序遍历和中序遍历重建二叉树原创 2017-07-30 14:12:37 · 253 阅读 · 0 评论 -
判断一颗二叉树是是否是另一颗树的子树
判断一颗二叉树是是否是另一颗树的子树原创 2017-07-31 10:26:41 · 380 阅读 · 0 评论 -
判断一个节点是否在一棵二叉树中
使用前序遍历判断原创 2017-07-31 10:30:32 · 741 阅读 · 1 评论 -
C++引用与指针
引用:某一变量的别名。与指针类似。原创 2017-03-08 23:27:53 · 300 阅读 · 0 评论 -
C++命名空间相关解析
使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突。 在多文件编译时,多个全局变量取名重复了,产生了命名冲突,这样的程序在C中,是无法通过编译的。如果两个人写的库文件中出现同名的变量或函数(不可避免),使用起来就有问题了。原创 2017-03-09 11:47:13 · 273 阅读 · 0 评论 -
this指针
this指针作为一个隐含参数传递给非静态成员函数,用以指向该成员函数所属类所定义的对象。原创 2017-03-10 23:11:50 · 324 阅读 · 0 评论 -
类的六个默认成员函数
类中,默认生成六个成员函数:构造函数拷贝构造函数析构函数赋值运算符重载取地址(&)运算符重载const修饰的取地址运算符重载原创 2017-03-19 21:21:22 · 367 阅读 · 0 评论 -
腾讯笔试题:日期类
分享一道腾讯的笔试题,日期类。 主要还是在实现操作符重载。原创 2017-03-25 22:11:11 · 254 阅读 · 0 评论 -
C++中的继承
在初次接触到C++语言时,便了解到C++的三个重要特性:封装、继承、多态。 今天便来谈一谈继承。继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。这样产生新的类,称子类或派生类,已经存在的类成为基类或父类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。 通过继承,一个新建的子类从父类那里获得父类的特性。从另一角原创 2017-04-05 16:53:48 · 228 阅读 · 0 评论 -
C++中的多态问题
多态:即多种形态。 我们把具有继承关系的多个类型称为多态类型。 引用或指针的静态类型与动态类型不同这一事实正是c++语言支持多态性的根本所在。对象类型分为静态类型和动态类型。静态类型:对象编译阶段确定类型(又叫早绑定、静态绑定)动态类型:在程序执行阶段确定对象的类型(又叫晚绑定、动态绑定)静态多态:编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推 断出要调用原创 2017-04-13 21:11:16 · 350 阅读 · 0 评论 -
函数模板、类模板
当我们需要通过函数实现同一类而非同一种功能时,往往会通过一下几种方式来实现,但是他们又或多或少存在着各种各样的缺陷: 1.对函数进行重载,针对每个所需相同行为的不同类型重新实现它。 缺陷:一旦有新类型出现,就要重新添加对应函数。 代码的复用率很低 如果只是返回值类型不同,函数重载无法解决 不原创 2017-05-11 11:42:21 · 331 阅读 · 0 评论 -
初识智能指针+模拟auto_ptr
举个例子,当我们动态申请一块内存空间,使用完毕之后也正常释放该内存空间,但是若是在申请与释放中间,我们进行了异常处理,程序直接结束,则将造成内存泄漏。因此,我们引入智能指针。将自己申请的内存空间交给智能指针去处理。RAII(不能等同于智能指针)资源分配及初始化( Resource Acquisition Is Initialization)定义一个类来封装资源的分配和释放一种规范,一种解决问题的思想原创 2017-05-13 10:49:10 · 300 阅读 · 0 评论 -
scoped_ptr
通过上一篇博客,我们发现管理权转移这种方式存在问题较大,接下来我们看一下scoped_ptr。直接贴代码:template<typename T>class ScopedPtr{public: ScopedPtr(T* ptr = 0) :_ptr(ptr) {} T& operator*() { return *_原创 2017-05-13 11:37:13 · 343 阅读 · 0 评论 -
shared_ptr
先贴代码:template<typename T>class SharedPtr{public: SharedPtr(T* ptr = 0) :_ptr(ptr) { _count = new int(1); } SharedPtr(const SharedPtr<T>& sp) : _ptr(sp._ptr)原创 2017-05-14 14:13:31 · 218 阅读 · 0 评论 -
shared_ptr之定制删除器
shared_ptr是用来管理多种资源的,而我们现在往往会误认为用来管理动态开辟的内存空间,像是打开文件(fopen)、malloc等多种情况,也需要shared_ptr来管理,因此,我们便需要定制删除器。template<class T>class Free{ void operate()(T* _ptr) { free(_ptr);原创 2017-05-14 14:35:16 · 855 阅读 · 0 评论 -
C++类型萃取
在Seqlist中,我们对于内置类型,通过memcopy和memmove这两个方式进行拷贝,自定义类型或string类型我们要通过for循环赋值的方式拷贝。那么系统如何区分是哪种类型呢?虽然通过typeid可以获取变量类型,但是这样获取到的类型,无法用来做变量的声明。因此,我们这里引入类型萃取。#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>u原创 2017-05-15 11:30:05 · 277 阅读 · 0 评论 -
如何定义一个只能在堆上(栈上)生成对象的类?
在C++中,类的对象建立分为两种,一种是静态建立,如A a;另一种是动态建立,如A* ptr=new A;这两种方式是有区别的。静态建立一个类对象,是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造转载 2017-07-15 22:42:04 · 192 阅读 · 0 评论 -
关于C函数的调用过程——栈桢
栈桢通俗来讲,栈桢就是函数的调用过程。栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。原创 2017-01-12 15:48:04 · 858 阅读 · 0 评论 -
可变参数列表相关解读
可变参数列表实现求平均值最大值等功能原创 2017-01-12 16:17:01 · 369 阅读 · 0 评论 -
指针数组 数组指针 函数指针 函数指针数组 指向函数指针数组的指针
指针数组和数组指针指针数组:强调数组,然后数组中的元素都是指针,数组的大小是通过数组本身来决定。 数组指针:强调指针,就是说它还是一个指针变量,只不过他指向数组,至于他所指向的数组多大,这个就不知道了。int *p1[10];int (*p2)[10];指针数组和数组指针主要的区别主要是看优先级结合。”()”的优先级是最高的,下来是”[ ]”,再下来是”“;*int* p1[10]:根据优先原创 2017-02-14 13:17:29 · 363 阅读 · 0 评论 -
注视转换 将C风格注释转换为C++风格
C注释风格:/* */ C++注释风格: //原创 2017-03-09 11:10:23 · 363 阅读 · 0 评论 -
有关malloc的三个问题
有关于malloc的三个问题,困扰了很久,多处搜查资料,无奈对malloc的底层实现仍然不够透彻,将现阶段所获知的相关内容整理出来,后期再进一步完善。 1.如何知道申请的空间就是所需的空间大小 2.free的时候只给了指针那么如何知道该free多大的空间 3.申请空间的时候怎么知道哪些用了哪些没用。malloc函数是glibc提供的库函数。glibc的内存管理使用的方法是ptmal原创 2017-04-10 17:21:07 · 710 阅读 · 0 评论