红黑树(Red-black tree)基础
简介红黑树(Red–black tree)是一种自平衡二叉查找树,典型的用途是实现关联数组(Associative Array,又称映射Map、字典Dictionary)。它在1972年由鲁道夫·贝尔发明,被称为”对称二叉B树“。红黑树的结构复杂,但它的操作有着良好的最坏情况运行时间:它可以在O(log n)时间内完成查找,插入和删除,这里的n是树中元素的数目。
红黑树是2-3-4树( 也称4 阶B树,B树概括来说是一个一般化的二叉查找树BST,4阶指其每个节点最多包含 3 个元素和 4 个儿子)的一种等同。换句话说,对于每个2-3-4树,都存在至少一个数据元素是同样次序的红黑树。在2-3-4树上的插入和删除操作也等同于在红黑树中颜色翻转和旋转。这使得2-3-4树成为理解红黑树背后的逻辑的重要工具,这也是很多介绍算法的教科书在红黑树之前介绍2-3-4树的原因,尽管2-3-4树在实践中不经常使用。
The same red–black tree as in the example above, seen as a B-tree.
红黑树相对于AVL树(最早被发明的自平衡二叉查找树 ...
C++基础-杂记(一)
记录以下几点:
const修饰符
static修饰符
C++指针和引用的区别
堆和栈的区别
进程和线程的区别
字节序:大端法和小端法
const修饰符
const int m=7;:整型变量m的值为固定值7,不可改变
const int* p1 = &a;:
p1指向的值不可改变(简称 左定值,因为 const 位于 * 号左边)
*p1=b不合法,p2=&b合法
int* const p2 = &a;:
p2的指向不可改变(简称右定向,const 位于 * 号右边)
*p2=b合法,p2=&b不合法
1234567891011121314int a = 7;int b = 8;//===左定值,值(*p1)不可变 (常量const指针*)const int* p1 = &a;p1 = &b;//ok//*p1 = b; // error!//===右定向,指向(p2)不可变 (指针*常量const)int* const p2 = &a;//p2 = &b; // error!*p2 = b; ...
C++基础-智能指针
智能指针基础原理智能指针和普通指针的区别在于智能指针实际上是对普通指针加了一层封装机制,这样的一层封装机制的目的是为了使得智能指针可以方便的管理一个对象的生命期,实现内存的自我回收。
对于普通的 局部变量(非静态局部变量),当离开它的作用域时,操作系统会自动将其释放。类对象在释放的时候是会自动调用该类的析构函数。
于是我们就想:如果是Test *t不是一个普通的指针变量,而是一个类对象的话,并且在类的析构函数中实现了释放动态内存的步骤,那么只要该指针变量一退出作用域时就会调用析构函数,达到了释放动态内存的目的。这也就是智能指针的基本思想。
根据设想,在上篇文章最后一个示例程序的基础上可以自己实现一个最简易的智能指针:
12345678910111213141516171819202122232425262728293031323334353637383940#include <iostream>using namespace std;class Test{public: Test(int x = 0) :m_val(x) {}; ~Test ...
C++基础-指针使用注意
手动分配手动回收程序在运行的时候需要内存,在c/c++中,栈上的内存(如函数中的局部非静态变量)在使用完之后,操作系统会帮我们自动回收,而通过动态分配得到的 **堆上的内存 **,需要手动释放。
平时写一些小程序可能我们不太注意这一点,因为用到的内存较少,在程序结束后,忘记释放的内存也会被强制回收。如果是编写大型的持续运行的程序,不注意内存释放,会导致内存占用越来越高,影响系统性能或导致进程崩溃。
下面一个测试程序演示内存占用情况:
12345678910111213141516#include <iostream>using namespace std;int main(void){ int *p = (int*)malloc(sizeof(int)*2000000000);// 分配一块比较大的内存空间(根据电脑内存大小调整) cout << "p = " << p << endl;// 分配的指针的地址 *p = 10; cout << "*p = " << ...
C++多线程笔记(二)
unique_lock
unique_lock可完成lock_guard的功能,另外还有额外的参数,实现其它功能
unique_lock的defer_lock参数,即先不加锁,只是先绑定unique_lock与mutex,另外,可以 随时进行加锁、解锁操作,某些情况下可提高效率(注意此时的加、解锁是通过unique_lock的成员函数.lock() 与 .unlock()实现的)
unique_lock还可以 交换管理权(unique_lock可以被移动,lock_guard不可以)
代码示例:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455#include<iostream>#include<thread>#include<string>#include<mutex>#include<fstream>class LogFile{ std::mutex m ...
TensorFlow-VGG16模型复现
VGG介绍VGG全称是指牛津大学的Oxford Visual Geometry Group,该小组在2014年的ImageNet挑战赛中,设计的VGG神经网络模型在定位和分类跟踪比赛中分别取得了第一名和第二名的成绩。
VGG论文
VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION
论文指出其主要贡献在于:利用3*3小卷积核的网络结构对逐渐加深的网络进行全面的评估,结果表明加深网络深度到16至19层可极大超越前人的网络结构。
VGG结构特点
训练输入:固定尺寸224*224的RGB图像
预处理:每个像素值减去训练集上的RGB均值
卷积核:一系列3*3卷积核堆叠,步长为1,采用padding保持卷积后图像空间分辨率不变
空间池化:紧随卷积“堆”的最大池化,为2*2滑动窗口,步长为2
全连接层:特征提取完成后,接三个全连接层,前两个为4096通道,第三个为1000通道,最后是一个soft-max层,输出概率
所有隐藏层都用非线性修正ReLu
详细配置表中每列代表不同的网络,只有深度不同(层数计算不包 ...
TensorFlow-手写数字识别(三)
本篇文章在上篇TensorFlow-手写数字识别(二)的基础上,将全连接网络改为LeNet-5卷积神经网络,实现手写数字识别。
引言全连接网络:每个神经元与前后相邻层的每一个神经元都有连接关系,输入是特征,输出为预测的结果。
参数个数:Σ(前层x后层+后层)
如之前用于手写识别的3层全连接网络,输入层784个节点,隐藏层500个节点,输出层10个节点。则:
隐藏层参数:748*500+500
输出层参数:500*10+10
总计:397510≈40万
注:这里说的某层的参数是指该层与前一层之间的参数,因而输入层没有参数。
所以,一张分辨率仅仅是28x28的黑白图像,就有近40万个待优化的参数。现实生活中高分辨率的彩色图像,像素点更多,且为红绿蓝三通道信息。
待优化的参数过多, 容易导致模型过拟合。为避免这种现象,实际应用中一般不会将原始图片直接喂入全连接网络。而是先对原始图像进行特征提取,把提取到的特征喂给全连接网络,再让全连接网络计算出分类评估值。
CNN基础卷积 Convolutional卷积是一种有效提取图片特征的方法。一般用一个正方形卷积核,遍历图片上的每一个像素点。图 ...
TensorFlow填坑记录
RESTART:Shell(CuDNN 版本问题)问题描述
python IDLE中直接运行某些TensorFlow程序一切正常,运行卷积相关程序时自动退出,现象:
123456789>>> RESTART: G:\...\lenet5\mnist_lenet5_backward.py Extracting ./data/train-images-idx3-ubyte.gzExtracting ./data/train-labels-idx1-ubyte.gzExtracting ./data/t10k-images-idx3-ubyte.gzExtracting ./data/t10k-labels-idx1-ubyte.gz=============================== RESTART: Shell ===============================>>>
在命令行中运行python程序,现象:
12345678910111213G:\...\lenet5>python mnist_lenet5_back ...
TensorFlow-手写数字识别(二)
本篇文章在上篇TensorFlow-手写数字识别(一)的基础上进行改进,主要实现以下3点:
断点续训
测试真实图片
制作TFRecords格式数据集
断点续训上次的代码每次进行模型训练时,都会重新开始进行训练,之前的训练结果都被覆盖掉了,极不方便。
在backwork.py中加入ckpt操作,可以实现断点续训功能。
代码实现1234567891011121314with tf.Session() as sess: init_op = tf.global_variables_initializer() sess.run(init_op) ckpt = tf.train.get_checkpoint_state(MODEL_SAVE_PATH) if ckpt and ckpt.model_checkpoint_path: saver.restore(sess, ckpt.model_checkpoint_path) for i in range(STEPS): ...
TensorFlow-手写数字识别(一)
本篇文章通过TensorFlow搭建最基础的全连接网络,使用MNIST数据集实现基础的模型训练和测试。
MNIST数据集MNIST数据集 :包含7万张黑底白字手写数字图片,其中55000张为训练集,5000张为验证集,10000张为测试集。每张图片大小为28X28像素,图片中纯黑色像素值为0,纯白色像素值为1。数据集的标签是长度为10的一维数组,数组中每个元素索引号表示对应数字出现的概率 。
在将MNIST数据集作为输入喂入神经网络时,需先将数据集中每张图片变为长度784 一维数组,将该数组作为神经网络输入特征喂入神经网络。
例如:
一张数字手写体图片变成长度为 784 的一维数组[0.0.0.0.0.231 0.235 0.459……0.219 0.0.0.0.]输入神经网络。该图片对应的标签为[0.0.0.0.0.0.1.0.0.0],标签中索引号为 6 的元素为 1,表示是数字 6 出现的概率为 100%,则该图片对应的识别结果是 6。
使用input_data 模块中的read_data_sets()函数加载MNIST数据集:
12from tensorflow.exa ...