红黑树前世今生
关键词:二叉搜索树、前驱节点、后继节点、B树、红黑树
什么是B树
前世
B树是一种相对于来说特殊二叉搜索树,多用于数据库和文件搜索系统中。
n阶B树的性质
B树是一种平衡的多路搜索树,拥有平衡二叉树的一些特性,与平衡二叉树的最大区别在于每个节点不再是只能存储一个元素,而且每个节点可以拥有多个子节点而像二叉平衡树只能拥有两个。
1. B树每个节点最多可以存储超过2个元素,可以拥有超过2个子节点
2. B树每个子节点的子树高度一致
3. B树和二叉搜索树一样,左子树<根节点<右子树
4. 根节点元素个数: 1≤ X ≤ n - 1
5. 非根节点元素个数: n/2
二叉树今生
为什么会有二叉树这种数据结构?
思考一个问题:如果一个集合中有42亿个元素,让你从这42亿个元素中搜索某一个元素,你需要多少次操作?
如果使用数组链表的话最多可能需要42亿次比较,而如果使用二叉树我们只需要32次比较即可,这就是二叉树存在的价值。Java中的HashSet使用的就是二叉树
前驱与后继
前驱节点
1. 若一个节点有左子树,那么该节点的前驱节点是其左子树中val值最大的节点(也就是左子树中所谓的rightMostNode)
2. 若一个节点没有左子树,那么判断该节点和其父节点的关系
2.1 若该节点是其父节点的右边孩子,
iOS汇编基础
x86_64汇编
X84中原有8个32位通用寄存器%eax,%ebx,%ecx,%edx,%esi,%edi,%ebp,%esp,
X86_64中分别被扩展为64位,并且多了8个寄存器。因此X86_64的寄存器如下:
* rax, eax, ax, ah, al;
* rbx, ebx, bx, bh, bl;
* rcx, ecx, cx, ch, cl;
* rdx, edx, dx, dh, dl;
* rsi, esi, si;
* rdi, edi, di;
* rbp, ebp;
* rsp, esp;
* r8-r15;
GCC中对这些寄存
iOS图像优化技巧
* 1、如何处理大尺寸图片?
* 2、如何处理瀑布流图片占用大量内存的问题?
* 3、如何处理多张图片上传和下载问题?
1、处理大尺寸图片
那么,什么时候对图像进行渲染优化才有意义呢?
当它明显大于 UIImageView 显示尺寸的时候
想要完整渲染这张宽高为 12,000 px 的图片,需要高达 20 MB 的空间。对于当今的硬件来说,你可能不会在意这么少兆字节的占用。但那只是它压缩后的尺寸。要展示它,UIImageView 首先需要把 JPEG 数据解码成位图(bitmap),如果要在一个 UIImageVi
1、Hexo安装指南
1.1安装Node.js
首先下载稳定版Node.js。
安装选项全部默认,一路点击Next。
最后安装好之后,windows按Win+R打开命令提示符,mac打开命令行工具,输入node -v和npm -v,如果出现版本号,那么就安装成功了。
1.2添加国内镜像源
如果没有梯子的话,可以使用阿里的国内镜像进行加速。
1
npm config set registry https://registry.npm.taobao.org
1.3安装Git
为了把本地的网页文件上传到github上面去,我们需要用到分布式版本控制工具————Git[下载地址]。
深入理解GCD
dispatch_async 会把任务添加到队列的一个链表中,添加完后会唤醒队列,根据 vtable 中的函数指针,调用 wakeup 方法。
* 在 wakeup 方法中,从线程池里取出工作线程(如果没有就新建),然后在工作线程中取出链表头部指向的 block 并执行。
dispatch_sync 的实现略简单一些,它不涉及线程池(因此一般都在当前线程执行),而是利用与线程绑定的信号量来实现串行。
分发到不同队列时,代码进入的分支也不一样,比如 dispatch_async 到主队列的任务由 runloop 处理,而分发到其他队列的任务由线程池处理。
在当前串行队列
Runloop
1.讲讲 RunLoop,项目中有用到吗?
* 事件循环,在程序运行中循环做一些事情
* 没有消息mach_msg()切换用户态到内核态线程休眠,有消息内核态切换到用户态
runloop相关:
* Timer、performSelector
* GCD、AutoreleasePool
* 事件响应、收拾识别、网络请求
runloop的应用:
* 线程包活
* 解决timer滑动停止问题
* 监听主线程卡顿
* 性能优化
2.runloop的6种状态和runloop内部实现逻辑?
1
2
3
4
5
6
7
8
9
10
/* Run Loop Obs
SwiftTip
* 苹果官方文档
* NSHipster - is a journal of the overlooked bits in Objective-C, Swift, and Cocoa.
* NSBlog
* Flip the image: 翻转图片
* Retrive the paths: 检索,重新获得
问题记录
* 柯里化 什么意思
* POP 与 OOP的区别
* Any 与AnyObject 区别
* rethrows 和
带着问题去学习,是最有效的学习方法。所以按照惯例,我还是先给你出一个思考题:
问题一:为什么插入排序比冒泡排序更受欢迎?
如何分析一个“排序算法”?
* 最好情况、最坏情况、平均情况时间复杂度
* 时间复杂度的系数、常数、低阶
* 比较次数和交换次数
内存消耗
原地排序算法,就是特指空间复杂度是 O(1) 的排序算法。(冒泡排序、插入排序)
稳定性
* 经过某种排序算法排序之后,如果两个相同数值的前后顺序没有改变,那我们就把这种排序算法叫作稳定的排序算法;
* 如果前后顺序发生变化,那对应的排序算法就叫作不稳定的排序算
字符串反转
方法一:递归
原地反转字符串是否代表了空间复杂度为常数?
不,原地反转字符串是一种不使用辅助数据结构的算法。
我们使用递归的方法去反转字符串,它是原地反转,但是空间复杂度却不是常数级空间,因为递归过程中使用了堆栈空间。
算法过程
* 我们实现递归函数 helper,它接受两个参数:left 左指针和 right 右指针。
* 如果 left>=right,不做任何操作。
* 否则交换 s[left] 和 s[right] 和调用 helper(left + 1, right - 1)。
* 首次调用函数我们传递首尾指针反转整个字符串 return helper(0, l
老鼠毒药问题
1、有两个水桶, 一个装 3L 的水, 一个可装 5L 的水, 问:如何利用这两个桶, 量出 4L 的水来?
解法一加法:操作两次3L的桶,得到1L的水,然后倒入5L的桶里面,此时5L桶里有1L的水,再次用3L的桶倒入5L桶,1L+ 3L = 4L,一共操作3次3L桶
加法解法图示:
解法二减法:5L满水的桶倒入3L的桶,剩余2L,5L桶剩余的2L再次倒入3L桶,此时3L桶还有1L集满,5L桶再次装满后倒出来1L给3L桶里面,5L - 1L = 4L,连续操作3次5L桶
减法解法图示:
2、100个瓶子,里面有1瓶毒药,只有7只老鼠,老鼠吃了之后一星期会死亡,怎么测试