02 2018 档案

进程在Linux内核中的角色扮演
摘要:在Linux内核中,内核将进程、线程和内核线程一视同仁,即内核使用唯一的数据结构task_struct来分别表示他们;内核使用相同的调度算法对这三者进行调度;并且内核也使用同一个函数do_fork()来分别创建这三种执行线程(thread of execution)。执行线程通常是指任何正在执行的代 阅读全文

posted @ 2018-02-28 12:15 AlanTu 阅读(275) 评论(0) 推荐(0) 编辑

存储映射I/O
摘要:一个进程拥有独立并且连续虚拟地址空间,在32位体系结构中进程的地址空间是4G。不过,内核在管理进程的地址空间时是以内存区域为单位。内存区域是进程整个地址空间中一个独立的内存范围,它在内核中使用vm_area_struct数据结构来描述。每个内存区域都有自己访问权限以及操作函数,因此进程只能对有效范围 阅读全文

posted @ 2018-02-28 12:11 AlanTu 阅读(1192) 评论(0) 推荐(0) 编辑

伙伴算法的实现-分配页框
摘要:内核中alloc_pages系列页框分配函数都是基于伙伴算法实现的,这些函数最终都会调用伙伴算法的入口函数buffered_rmqueue()。 Linux内核管理物理内存有三种方式,其一就是经典的伙伴算法。但是伙伴算法分配物理内存的基本单位是页框,因此内核又引入了slab机制,基于此机制实现的物理 阅读全文

posted @ 2018-02-28 12:08 AlanTu 阅读(1563) 评论(0) 推荐(0) 编辑

内部排序算法小结
摘要:内部排序算法主要分为插入类排序、交换类排序和选择类排序,它们在性能上的差异主要体现在时间复杂度、空间复杂度和稳定性。各种排序算法都会进行元素间的比较和移动,时间复杂度主要由整个排序过程中的比较次数和移动次数决定。空间复杂度体现在除了待排序记录本身所占的空间,排序过程中占用了多少辅助空间。 1.插入类 阅读全文

posted @ 2018-02-28 12:05 AlanTu 阅读(417) 评论(0) 推荐(0) 编辑

typedef那回事儿
摘要:typedef是一种特殊的声明方式,不过它与普通声明(详见这里)的含义取大不相同。普通声明的主角是“变量”,它或是创建一个新变量或是对外文件变量使用前的声明;而typedef声明的主角则是“类型”,通过这个声明对一种数据类型引入新的名字。从引入新名字这个角度来说,typedef声明又和宏定义有些相似 阅读全文

posted @ 2018-02-28 12:01 AlanTu 阅读(430) 评论(0) 推荐(0) 编辑

声明那回事儿
摘要:C语言中的变量声明是让程序员比较苦恼的一件事,因为过多的优先级规则使得阅读声明并不能像自然方式那样从左至右的阅读。比如下面这个声明: int (*(*fun)())(); 对于这个声明,你能准确说出它的含义吗?这个声明涉及到本文的两大主题:什么是声明和声明的阅读规则。本文的最后将给出这个声明的准确含 阅读全文

posted @ 2018-02-28 11:53 AlanTu 阅读(147) 评论(0) 推荐(0) 编辑

C语言中的指针和数组
摘要:下面的内容节选自由我所执笔的会议记录。对于本文的不足之处,各位可以提出自己的看法。 Q1:指针和数组到底是怎么一回事? A:指针和数组有本质的不同。指针就是一个内存地址,在32位系统下,一个指针永远占4个字节;数组是一块连续的内存空间,我们从一个已定义的数组中可以获得数组大小以及这块连续内存空间的起 阅读全文

posted @ 2018-02-28 11:47 AlanTu 阅读(288) 评论(0) 推荐(0) 编辑

C语言笔记本
摘要:在此记录一些常见的C语言错误,可以当作学习C语言的笔记,需要的时候可以回过头看看。 1.关于“++” 关于自加自减运算符用于句话就可以总结:a++先使用后自加,++a先自加再引用。这样就可以轻松得出结果: 2.交换变量 第一种方法即中间变量法,下面说明第二种,不添加中间变量: 3.char* str 阅读全文

posted @ 2018-02-28 11:44 AlanTu 阅读(423) 评论(0) 推荐(0) 编辑

西邮Linux兴趣小组纳新笔试试题
摘要:下面是西邮Linux小组今年纳新的笔试试题 1、 下面这个程序的输出结果是什么? int main() { int a = (1, 2); printf(“a = %d\n”, a); return 0; } 解答: a = 2 这里利用了逗号表达式。 2、下面这个程序的输出结果是什么? struc 阅读全文

posted @ 2018-02-28 11:40 AlanTu 阅读(363) 评论(0) 推荐(0) 编辑

[译]《数学:更好的解释》之培养数学直觉
摘要:Developing Your Intuition For Math Our initial exposure to an idea shapes our intuition. And our intuition impacts how much we enjoy a subject. What d 阅读全文

posted @ 2018-02-27 14:41 AlanTu 阅读(848) 评论(0) 推荐(0) 编辑

你是想读书,还是想读完书?
摘要:以前,读书前会很想读一本书,但实际读书时,经常是“想读完书”,而不是“想读书”。这种想法经常会让我的生活变得很痛苦,当你做一件事想着快点做完时,你的心思其实已经不在这件事上了。 这个问题在我大学时困扰了我很久。我没有意识到这本身其实是一个价值观问题,以至于我常在一些时间管理的书中寻找答案。那些书都只 阅读全文

posted @ 2018-02-27 14:37 AlanTu 阅读(304) 评论(0) 推荐(0) 编辑

给计算机专业大学生整理的书单
摘要:作者: [美] Charles Petzold出版社: 电子工业出版社副标题: 隐匿在计算机软硬件背后的语言原作名: Code: The Hidden Language of Computer Hardware and Software译者: 左飞 / 薛佟佟出版年: 2010页数: 392定价: 阅读全文

posted @ 2018-02-27 14:35 AlanTu 阅读(8112) 评论(0) 推荐(2) 编辑

理解矩阵(三)
摘要:在第二部分结束的时候,我说: “矩阵不仅可以作为线性变换的描述,而且可以作为一组基的描述。而 作为变换的矩阵,不但可以把线性空间中的一个点给变换到另一个点去,而且也能够把线性空间中的一个坐标系(基)表换到另一个坐标系(基)去。而且,变换点 与变换坐标系,具有异曲同工的效果。线性代数里最有趣的奥妙,就 阅读全文

posted @ 2018-02-27 14:23 AlanTu 阅读(336) 评论(0) 推荐(0) 编辑

理解矩阵(二)
摘要:上一篇里说“矩阵是运动的描述”,到现在为止,好像大家都还没什么意见。但是我相信早晚会有数学系出身的网友来拍板转。因为运动这个概念,在数学和物理里是跟微积分联系在一起的。我们学习微积分的时候,总会有人照本宣科地告诉你,初等数学是研究常量的数学,是研究静态的数学,高等数学是变量的数学,是研究运动的数学。 阅读全文

posted @ 2018-02-27 14:22 AlanTu 阅读(257) 评论(0) 推荐(0) 编辑

理解矩阵(一)
摘要:前不久chensh出于不可告人的目的,要充当老师,教别人线性代数。于是我被揪住就线性代数中一些务虚性的问题与他讨论了几次。很明显,chensh觉得,要让自己在讲线性代数的时候不被那位强势的学生认为是神经病,还是比较难的事情。 可怜的chensh,谁让你趟这个地雷阵?!色令智昏啊! 线性代数课程,无论 阅读全文

posted @ 2018-02-27 14:20 AlanTu 阅读(608) 评论(0) 推荐(1) 编辑

命名管道FIFO和mkfifo函数
摘要:进程间通信必须通过内核提供的通道,而且必须有一种办法在进程中标识内核提供的某个通道,前面讲过的匿名管道是用打开的文件描述符来标识的。如果要互相通信的几个进程没有从公共祖先那里继承文件描述符,它们怎么通信呢?内核提供一条通道不成问题,问题是如何标识这条通道才能使各进程都可以访问它?文件系统中的路径名是 阅读全文

posted @ 2018-02-27 10:09 AlanTu 阅读(7364) 评论(0) 推荐(0) 编辑

管道读写规则和Pipe Capacity、PIPE_BUF
摘要:一、当没有数据可读时 O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止。 O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。 示例程序如下: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 阅读全文

posted @ 2018-02-27 10:07 AlanTu 阅读(1659) 评论(0) 推荐(0) 编辑

匿名管道和pipe函数
摘要:一、进程间通信 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Com 阅读全文

posted @ 2018-02-27 10:04 AlanTu 阅读(1657) 评论(0) 推荐(1) 编辑

竞态条件与sigsuspend函数
摘要:一、利用pause和alarm函数实现sleep函数 #include <unistd.h> int pause(void); pause函数使调用进程挂起直到有信号递达。如果信号的处理动作是终止进程,则进程终止,pause函数没有机会返回;如果信号的处理动作是忽略,则进程继续处于挂起状态,paus 阅读全文

posted @ 2018-02-27 10:03 AlanTu 阅读(409) 评论(0) 推荐(0) 编辑

实时信号与sigqueue函数
摘要:一、sigqueue函数 功能:新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用。 原型:int sigqueue(pid_t pid, int sig, const union sigval value); 参数: sigqueue的第一个参数是 阅读全文

posted @ 2018-02-27 10:01 AlanTu 阅读(1266) 评论(0) 推荐(0) 编辑

信号的捕捉与sigaction函数
摘要:一、内核如何实现信号的捕捉 如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。由于信号处理函数的代码是在用户空间的,处理过程比较复杂,举例如下: 1. 用户程序注册了SIGQUIT信号的处理函数sighandler。 2. 当前正在执行main函数,这时发生中断或异常切 阅读全文

posted @ 2018-02-27 10:00 AlanTu 阅读(3575) 评论(1) 推荐(0) 编辑

信号的阻塞与未决
摘要:一、信号在内核中的表示 实际执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending)。进程可以选择阻塞(Block)某个信号,SIGKILL 和 SIGSTOP 不能被阻塞。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递 阅读全文

posted @ 2018-02-27 09:58 AlanTu 阅读(1225) 评论(0) 推荐(0) 编辑

一些信号发送函数和不同精度的睡眠
摘要:一、kill, raise, killpg 函数 int kill(pid_t pid, int sig); int raise(int sig); int killpg(int pgrp, int sig); kill命令是调用kill函数实现的,kill函数可以给一个指定的进程或进程组发送指定的 阅读全文

posted @ 2018-02-27 09:56 AlanTu 阅读(259) 评论(0) 推荐(0) 编辑

信号基本概述
摘要:一、为了理解信号,先从我们最熟悉的场景说起: 1. 用户输入命令,在Shell下启动一个前台进程。 2. 用户按下Ctrl-C,这个键盘输入产生一个硬件中断。 3. 如果CPU当前正在执行这个进程的代码,则该进程的用户空间代码暂停执行,CPU从用户态切换到内核态处理硬件中断。 4. 终端驱动程序将C 阅读全文

posted @ 2018-02-27 09:53 AlanTu 阅读(374) 评论(0) 推荐(0) 编辑

终端、作业控制与守护进程
摘要:一、终端的概念 在UNIX系统中,用户通过终端登录系统后得到一个Shell进程,这个终端成为Shell进程的控制终端(Controlling Terminal),控制终端是保存在PCB中的信息,而我们知道fork会复制PCB中的信息,因此由Shell进程启动的其它进程的控制终端也是这个终端。默认情况 阅读全文

posted @ 2018-02-27 09:50 AlanTu 阅读(470) 评论(0) 推荐(0) 编辑

wait/waitpid函数与僵尸进程、fork 2 times
摘要:一、僵尸进程 当子进程退出的时候,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程,它只保留最小的一些内核数据结构,以便父进程查询子进程的退出状态。 A child that term 阅读全文

posted @ 2018-02-27 09:48 AlanTu 阅读(743) 评论(0) 推荐(0) 编辑

exec系列函数和system函数
摘要:一、exec替换进程映象 在进程的创建上Unix采用了一个独特的方法,它将进程创建与加载一个新进程映象分离。这样的好处是有更多的余地对两种操作进行管理。当我们创建 了一个进程之后,通常将子进程替换成新的进程映象,这可以用exec系列的函数来进行。当然,exec系列的函数也可以将当前进程替换掉。 二、 阅读全文

posted @ 2018-02-27 09:47 AlanTu 阅读(3825) 评论(0) 推荐(0) 编辑

fork函数相关总结
摘要:fork的作用是根据一个现有的进程复制出一个新进程,原来的进程称为父进程(Parent Process),新进程称为子进程(Child Process)。系统中同时运行着很多进程,这些进程都是从最初只有一个进程开始一个一个复制出来的。在Shell下输入命令可以运行一个程序,是因为Shell进程在读取 阅读全文

posted @ 2018-02-27 09:44 AlanTu 阅读(461) 评论(0) 推荐(0) 编辑

文件的内核结构file和dup实现重定向
摘要:一、打开文件内核数据结构 1、一个进程打开两个文件 文件状态标志:读、写、追加、同步、非阻塞等 2、一个进程两次打开同一文件 3、两个进程打开同一文件 示例程序: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 阅读全文

posted @ 2018-02-27 09:42 AlanTu 阅读(562) 评论(0) 推荐(0) 编辑

进程基本概述
摘要:一、什么是进程 从用户的角度来看进程是程序的一次执行过程。 从操作系统的核心来看,进程是操作系统分配的内存、CPU时间片等资源的基本单位。 进程是资源分配的最小单位。 每一个进程都有自己独立的地址空间与执行状态。 像UNIX这样的多任务操作系统能够让许多程序同时运行,每一个运行着的程序就构成了一个进 阅读全文

posted @ 2018-02-27 09:40 AlanTu 阅读(559) 评论(0) 推荐(0) 编辑

fcntl 函数与文件锁
摘要:一、fcntl函数 功能:操纵文件描述符,改变已打开的文件的属性 int fcntl(int fd, int cmd, ... /* arg */ ); cmd的取值可以如下: 复制文件描述符 F_DUPFD (long) 设置/获取文件描述符标志 F_GETFD (void) F_SETFD (l 阅读全文

posted @ 2018-02-27 09:38 AlanTu 阅读(679) 评论(0) 推荐(0) 编辑

文件的属性
摘要:一、读取文件元数据 int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); int lstat(const char *path, struct stat *buf); stat() sta 阅读全文

posted @ 2018-02-27 09:36 AlanTu 阅读(260) 评论(0) 推荐(0) 编辑

目录的操作
摘要:一、目录的访问 功能说明:打开一个目录 原型:DIR* opendir(char *pathname); 返回值:打开成功,返回一个目录指针打开失败,则返回NULL 功能说明:访问指定目录中下一个连接的细节 原型:struct dirent* readdir(DIR *dirptr); 返回值:返回 阅读全文

posted @ 2018-02-27 09:35 AlanTu 阅读(148) 评论(0) 推荐(0) 编辑

文件的读取写入
摘要:一、read系统调用 一旦有了与一个打开文件描述相关连的文件描述符,只要该文件是用O_RDONLY或O_RDWR标志打开的,就可以用read()系统调用从该文件中读取字节 函数原型: ssize_t read(int fd, void *buf, size_t count); 参数: fd :想要读 阅读全文

posted @ 2018-02-27 09:32 AlanTu 阅读(437) 评论(0) 推荐(0) 编辑

文件的打开关闭
摘要:一、文件描述符 对于Linux而言,所有对设备或文件的操作都是通过文件描述符进行的。当打开或者创建一个文件的时候,内核向进程返回一个文件描述符(非负整数)。后续对文件的操作只需通过该文件描述符,内核记录有关这个打开文件的信息(file结构体)。 一个进程启动时,默认打开了3个文件,标准输入、标准输出 阅读全文

posted @ 2018-02-27 09:30 AlanTu 阅读(521) 评论(0) 推荐(0) 编辑

浅谈原始套接字 SOCK_RAW 的内幕及其应用(port scan, packet sniffer, syn flood, icmp flood)
摘要:一、SOCK_RAW 内幕 首先在讲SOCK_RAW 之前,先来看创建socket 的函数: int socket(int domain, int type, int protocol); domain :指定通信协议族(protocol family/address) /usr/include/i 阅读全文

posted @ 2018-02-27 09:28 AlanTu 阅读(1781) 评论(0) 推荐(0) 编辑

socket 请求接收完整的一个http响应(设置recv 接收超时选项SO_RCVTIMEO)
摘要:在前面的系列网络编程文章中,我们都是使用socket 自己实现客户端和服务器端来互相发数据测试,现在尝试使用socket 客户端发 送http 请求给某个网站,然后接收网站的响应数据。http 协议参考 这里。 代码如下: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 阅读全文

posted @ 2018-02-27 09:22 AlanTu 阅读(3077) 评论(0) 推荐(0) 编辑

posix 条件变量与互斥锁 示例生产者--消费者问题
摘要:一、posix 条件变量 一种线程间同步的情形:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行。 在pthread库中通过条件变量(Condition Variable)来阻塞等待一个条件,或者唤醒等待这个条 阅读全文

posted @ 2018-02-27 09:19 AlanTu 阅读(406) 评论(0) 推荐(0) 编辑

posix 匿名信号量与互斥锁 示例生产者--消费者问题
摘要:一、posix 信号量 信号量的概念参见这里。前面也讲过system v 信号量,现在来说说posix 信号量。 system v 信号量只能用于进程间同步,而posix 信号量除了可以进程间同步,还可以线程间同步。system v 信号量每次PV操作可以是N,但Posix 信号量每次PV只能是1。 阅读全文

posted @ 2018-02-27 09:17 AlanTu 阅读(987) 评论(0) 推荐(0) 编辑

线程的属性和 线程特定数据 Thread-specific Data
摘要:一、posix 线程属性 POSIX 线程库定义了线程属性对象 pthread_attr_t ,它封装了线程的创建者可以访问和修改的线程属性。主要包括如下属性: 1. 作用域(scope) 2. 栈尺寸(stack size) 3. 栈地址(stack address) 4. 优先级(priorit 阅读全文

posted @ 2018-02-27 09:14 AlanTu 阅读(775) 评论(0) 推荐(0) 编辑

线程模型、pthread 系列函数 和 简单多线程服务器端程序
摘要:一、线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属于1:1模型。 (一)、N:1用户线程模型 “线程实现”建立在“进程控制”机制之上,由用户空间的程序库来管理。OS内核完全不知道线程信息。这些线程称为用户空间线程。这些线程都工作在“进 程 阅读全文

posted @ 2018-02-27 09:12 AlanTu 阅读(1636) 评论(0) 推荐(0) 编辑

POSIX 共享内存和 系列函数
摘要:在前面介绍了system v 共享内存的相关知识,现在来稍微看看posix 共享内存 和系列函数。 共享内存简单来说就是一块真正的物理内存区域,可以使用一些函数将这块区域映射到进程的地址空间进行读写,而posix 共享内存与system v 共享内存不同的是它是用虚拟文件系统(tmpfs)实现的,已 阅读全文

posted @ 2018-02-27 09:04 AlanTu 阅读(838) 评论(0) 推荐(0) 编辑

POSIX 消息队列 和 系列函数
摘要:一、在前面介绍了system v 消息队列的相关知识,现在来稍微看看posix 消息队列。 posix消息队列的一个可能实现如下图: 其实消息队列就是一个可以让进程间交换数据的场所,而两个标准的消息队列最大的不同可能只是api 函数的不同,如system v 的系列函数是msgxxx,而posix 阅读全文

posted @ 2018-02-27 09:02 AlanTu 阅读(726) 评论(0) 推荐(0) 编辑

用信号量实现进程互斥示例和解决哲学家就餐问题
摘要:一、我们在前面讲进程间通信的时候提到过进程互斥的概念,下面写个程序来模拟一下,程序流程如下图: 即父进程打印字符O,子进程打印字符X,每次打印一个字符后要sleep 一下,这里要演示的效果是,在打印程序的边界有PV操作,故每个进程中间sleep 的时间即使时间片轮转到另一进程,由于资源不可用也不会穿 阅读全文

posted @ 2018-02-26 14:40 AlanTu 阅读(2368) 评论(0) 推荐(0) 编辑

封装一个信号量集操作函数的工具
摘要:信号量的概念参见这里。 与消息队列和共享内存一样,信号量集也有自己的数据结构: struct semid_ds { struct ipc_perm sem_perm; /* Ownership and permissions */ time_t sem_otime; /* Last semop ti 阅读全文

posted @ 2018-02-26 14:38 AlanTu 阅读(512) 评论(0) 推荐(0) 编辑

System V 共享内存 和 系列函数
摘要:跟消息队列一样,共享内存也有自己的数据结构,如下: struct shmid_ds { struct ipc_perm shm_perm; /* Ownership and permissions */ size_t shm_segsz; /* Size of segment (bytes) */ 阅读全文

posted @ 2018-02-26 14:36 AlanTu 阅读(338) 评论(0) 推荐(0) 编辑

共享内存简介和mmap 函数
摘要:一、共享内存简介 共享内存区是最快的IPC形式,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。 即每个进程地址空间都有一个共享存储器的映射区,当这块区域都映射到相同的真正的物理地址空间时,可以通过这块区域进行数据交换,例如共享库就是这么实现的,很多进 阅读全文

posted @ 2018-02-26 14:34 AlanTu 阅读(2024) 评论(0) 推荐(0) 编辑

消息队列实现回射客户/服务器和 msgsnd、msgrcv 函数
摘要:一、msgsnd 和 msgrcv 函数 #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> 功能:把一条消息添加到消息队列中 原型 int msgsnd(int msqid, const void *msgp, size 阅读全文

posted @ 2018-02-26 14:33 AlanTu 阅读(1520) 评论(0) 推荐(0) 编辑

消息队列内核结构和msgget、msgctl 函数
摘要:一、消息队列 1、消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法 2、每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值 3、消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的,且消息队列的读取不一定是先入先出。 4、消息队列也有管道一样的不足,就 阅读全文

posted @ 2018-02-26 14:30 AlanTu 阅读(5971) 评论(0) 推荐(0) 编辑

进程间通信概述
摘要:一、顺序程序与并发程序特征 顺序程序特征 顺序性 封闭性:(运行环境的封闭性) 确定性 可再现性 并发程序特征 共享性 并发性 随机性 二、进程互斥 1、由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥 2、系统中某些资源一次只允许一个进程使 阅读全文

posted @ 2018-02-26 14:27 AlanTu 阅读(278) 评论(0) 推荐(0) 编辑

通过UNIX域套接字传递描述符和 sendmsg/recvmsg 函数
摘要:在前面我们介绍了UNIX域套接字编程,更重要的一点是UNIX域套接字可以在同一台主机上各进程之间传递文件描述符。 下面先来看两个函数: #include <sys/types.h> #include <sys/socket.h> ssize_t sendmsg(int sockfd, const s 阅读全文

posted @ 2018-02-26 14:25 AlanTu 阅读(1335) 评论(0) 推荐(0) 编辑

UNIX域套接字编程和socketpair 函数
摘要:一、UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX D 阅读全文

posted @ 2018-02-26 14:23 AlanTu 阅读(3262) 评论(0) 推荐(1) 编辑

基于UDP协议的网络程序
摘要:一、下图是典型的UDP客户端/服务器通讯过程 下面依照通信流程,我们来实现一个UDP回射客户/服务器 #include <sys/types.h> #include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t len 阅读全文

posted @ 2018-02-26 14:21 AlanTu 阅读(2393) 评论(0) 推荐(0) 编辑

epoll 系列函数简介、与select、poll 的区别
摘要:一、epoll 系列函数简介 #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags); int epoll_ctl(int epfd, int op, int fd, struct epoll_e 阅读全文

posted @ 2018-02-26 14:20 AlanTu 阅读(2691) 评论(0) 推荐(0) 编辑

select函数的并发限制和 poll 函数应用举例
摘要:一、用select实现的并发服务器,能达到的并发数,受两方面限制 1、一个进程能打开的最大文件描述符限制。这可以通过调整内核参数。可以通过ulimit -n来调整或者使用setrlimit函数设置, 但一个系统所能打开的最大数也是有限的,跟内存大小有关,可以通过cat /proc/sys/fs/fi 阅读全文

posted @ 2018-02-26 14:18 AlanTu 阅读(689) 评论(0) 推荐(0) 编辑

套接字I/O超时设置方法和用select实现超时
摘要:注:如无特殊说明,sockfd 原始状态都是阻塞的。 一、使用alarm 函数设置超时 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 void handler(int sig) { } signal(SIGALRM, handler); alarm(5); int r 阅读全文

posted @ 2018-02-26 14:16 AlanTu 阅读(1010) 评论(0) 推荐(0) 编辑

shutdown 与 close 函数 的区别
摘要:假设server和client 已经建立了连接,server调用了close, 发送FIN 段给client(其实不一定会发送FIN段,后面再说),此时server不能再通过socket发送和接收数据,此时client调用read,如果接收到FIN 段会返回0,但client此时还是可以write 阅读全文

posted @ 2018-02-26 14:13 AlanTu 阅读(288) 评论(0) 推荐(0) 编辑

使用select函数改进客户端/服务器端程序
摘要:一、当我们使用单进程单连接且使用readline修改后的客户端程序,去连接使用readline修改后的服务器端程序,会出现一个有趣的现象,先来看输出: 先运行服务器端,再运行客户端, simba@ubuntu:~/Documents/code/linux_programming/UNP/socket 阅读全文

posted @ 2018-02-26 14:11 AlanTu 阅读(1488) 评论(0) 推荐(0) 编辑

五种I/O模型和select函数简介
摘要:一、五种I/O模型 1、阻塞I/O 我们在前面所说的I/O模型都是阻塞I/O,即调用recv系统调用,如果没有数据则阻塞等待,当数据到来则将数据从内核空间(套接口缓冲区)拷贝到用户空间(recv函数提供的buf),然后recv返回,进行数据处理。 2、非阻塞I/O 我们可以使用 fcntl(fd, 阅读全文

posted @ 2018-02-26 14:08 AlanTu 阅读(920) 评论(0) 推荐(0) 编辑

一个进程发起多个连接和gethostbyname等函数
摘要:一、在前面讲过的最简单的回射客户/服务器程序中,一个客户端即一个进程,只会发起一个连接,只要稍微修改一下就可以让一个客户端发起多个连 接,然后只利用其中一个连接发送数据。 先来认识一个函数getsockname #include <sys/socket.h> int getsockname(int 阅读全文

posted @ 2018-02-26 14:05 AlanTu 阅读(604) 评论(0) 推荐(0) 编辑

利用recv和readn函数实现readline函数
摘要:在前面的文章中,我们为了避免粘包问题,实现了一个readn函数读取固定字节的数据。如果应用层协议的各字段长度固定,用readn来读是非常方便 的。例如设计一种客户端上传文件的协议,规定前12字节表示文件名,超过12字节的文件名截断,不足12字节的文件名用'\0'补齐,从第13字节开始是 文件内容,上 阅读全文

posted @ 2018-02-26 14:03 AlanTu 阅读(974) 评论(1) 推荐(2) 编辑

tcp流协议产生的粘包问题和解决方案
摘要:我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议 阅读全文

posted @ 2018-02-26 14:01 AlanTu 阅读(888) 评论(0) 推荐(0) 编辑

使用fork并发处理多个client的请求和对等通信p2p
摘要:一、在前面讲过的回射客户/服务器程序中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现。网络服务器通常用fork来同时服务多个客户端,父进程专门负责监听端口,每次accept一个新的客户端连接就f 阅读全文

posted @ 2018-02-26 13:59 AlanTu 阅读(724) 评论(0) 推荐(0) 编辑

最简单的回射客户/服务器程序、time_wait 状态
摘要:下面通过最简单的客户端/服务器程序的实例来学习socket API。 echoser.c 程序的功能是从客户端读取字符然后直接回射回去。 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 阅读全文

posted @ 2018-02-26 13:56 AlanTu 阅读(389) 评论(0) 推荐(0) 编辑

C/S程序的一般流程和基本socket函数
摘要:一、基于TCP协议的网络程序 下图是基于TCP协议的客户端/服务器程序的一般流程: 服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服 阅读全文

posted @ 2018-02-26 13:54 AlanTu 阅读(1002) 评论(0) 推荐(0) 编辑

socket概述和字节序、地址转换函数
摘要:一、什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口。 socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信。 socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及以后要讲的UNIX Domain So 阅读全文

posted @ 2018-02-26 13:53 AlanTu 阅读(1245) 评论(0) 推荐(0) 编辑

分析一帧基于UDP的TFTP协议帧
摘要:下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度。 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: 00 05 5d 67 d0 b1 00 05 5d 61 58 a8 08 00 IP首部 000 阅读全文

posted @ 2018-02-26 13:52 AlanTu 阅读(1298) 评论(0) 推荐(0) 编辑

IP数据报格式和IP地址路由
摘要:一、IP数据报格式 IP数据报格式如下: 注:需要注意的是网络数据包以大端字节序传输,当然头部也得是大端字节序,也就是说: The most significant bit is numbered 0 at the left, and the least significant bit of a 3 阅读全文

posted @ 2018-02-26 13:49 AlanTu 阅读(3223) 评论(0) 推荐(0) 编辑

利用ARP和ICMP协议解释ping命令
摘要:一、MTU 以太网和IEEE 802.3对数据帧的长度都有限制,其最大值分别是1500和1492字节,将这个限制称作最大传输单元(MTU,Maximum Transmission Unit)。如果IP层有一个数据报要传,而且数据的长度比链路层的MTU还大,那么IP层就要进行分片(Fragmentat 阅读全文

posted @ 2018-02-26 13:48 AlanTu 阅读(6070) 评论(0) 推荐(0) 编辑

TCP/IP协议栈与数据报封装
摘要:一、ISO/OSI参考模型 OSI(open system interconnection)开放系统互联模型是由ISO(International Organization for Standardization)国际标准化组织定义的网络分层模型,共七层,如下图。 物理层(Physical Laye 阅读全文

posted @ 2018-02-26 13:46 AlanTu 阅读(3115) 评论(0) 推荐(0) 编辑

从汇编角度来理解linux下多层函数调用堆栈运行状态
摘要:我们用下面的C代码来研究函数调用的过程。 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int bar(int c, int d) { int e = c + d; return e; }int foo(int a, int b) { return  阅读全文

posted @ 2018-02-26 13:36 AlanTu 阅读(544) 评论(0) 推荐(0) 编辑

read/write函数与(非)阻塞I/O的概念
摘要:一、read/write 函数 read函数从打开的设备或文件中读取数据。 #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); 返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件 阅读全文

posted @ 2018-02-26 13:34 AlanTu 阅读(5258) 评论(0) 推荐(0) 编辑

可重入函数、线程安全、volatile
摘要:一、 POSIX 中对可重入和线程安全这两个概念的定义: Reentrant Function:A function whose effect, when called by two or more threads,is guaranteed to be as if the threads each 阅读全文

posted @ 2018-02-26 13:32 AlanTu 阅读(321) 评论(0) 推荐(0) 编辑

Linux进程地址空间和虚拟内存
摘要:一、虚拟内存 先来看一张图(来自《Linux内核完全剖析》),如下: 分段机制:即分成代码段,数据段,堆栈段。每个内存段都与一个特权级相关联,即0~3,0具有最高特权级(内核),3则是最低特权级(用户),每当程序试图访问(权限又分为可读、可写和可执行)一个段时,当前特权级CPL就会与段的特权级进行比 阅读全文

posted @ 2018-02-26 13:30 AlanTu 阅读(2397) 评论(0) 推荐(0) 编辑

C 标准库IO缓冲区和内核缓冲区的区别
摘要:1.C标准库的I/O缓冲区 UNIX的传统 是Everything is a file,键盘、显示器、串口、磁盘等设备在/dev 目录下都有一个特殊的设备文件与之对应,这些设备文件也可以像普通文件(保存在磁盘上的文件)一样打开、读、写和关闭,使用的函数接口是相同的。用户程序调用C标准I/O库函数读写 阅读全文

posted @ 2018-02-26 13:28 AlanTu 阅读(2219) 评论(1) 推荐(1) 编辑

文件描述符file descriptor与inode的相关知识
摘要:每个进程在Linux内核中都有一个task_struct结构体来维护进程相关的 信息,称为进程描述符(Process Descriptor),而在操作系统理论中称为进程控制块 (PCB,Process Control Block)。task_struct中有一个指针(struct files_str 阅读全文

posted @ 2018-02-26 13:26 AlanTu 阅读(643) 评论(0) 推荐(0) 编辑

C 标准IO 库函数与Unbuffered IO函数
摘要:先来看看C标准I/O库函数是如何用系统调用实现的。 fopen(3) 调用open(2)打开指定的文件,返回一个文件描述符(就是一个int 类型的编号),分配一 个FILE 结构体, 通常里面包含了: 文件fd 缓冲区指针 缓冲区长度 当前缓冲区读取长度 出错标志 返回这 个FILE 结构体的地址。 阅读全文

posted @ 2018-02-26 13:25 AlanTu 阅读(416) 评论(0) 推荐(0) 编辑

计算机体系结构一点基础知识
摘要:下面这张图来自《深入理解计算机系统》: IO桥部分一般还分为北桥和南桥,北桥当然是靠上的了。 •CPU –主频: CPU的时钟频率,内核工作的时钟频率 –外频: 系统总线的工作频率 –倍频: CPU外频与主频相差的倍数 –前端总线: 将CPU连接到北桥芯片的总线 –总线频率: 与外频相同或者是外频的 阅读全文

posted @ 2018-02-26 13:24 AlanTu 阅读(1252) 评论(0) 推荐(1) 编辑

套接字socket 的地址族和类型、工作原理、创建过程
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 11:01 AlanTu 阅读(1920) 评论(0) 推荐(0) 编辑

Ext2文件系统布局,文件数据块寻址,VFS虚拟文件系统
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 11:00 AlanTu 阅读(1066) 评论(0) 推荐(0) 编辑

内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 10:58 AlanTu 阅读(1605) 评论(0) 推荐(0) 编辑

X86 寻址方式、AT&T 汇编语言相关知识、AT&T 与 Intel 汇编语言的比较、gcc 嵌入式汇编
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 10:56 AlanTu 阅读(1358) 评论(0) 推荐(0) 编辑

进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 10:53 AlanTu 阅读(1452) 评论(0) 推荐(0) 编辑

时间系统、进程的调度与切换
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 10:50 AlanTu 阅读(2852) 评论(0) 推荐(0) 编辑

进程控制块PCB结构 task_struct 描述
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 10:49 AlanTu 阅读(1276) 评论(0) 推荐(0) 编辑

中断机制和中断描述符表、中断和异常的处理
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 10:47 AlanTu 阅读(1594) 评论(0) 推荐(0) 编辑

80386的分段机制、分页机制和物理地址的形成
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 10:46 AlanTu 阅读(892) 评论(0) 推荐(0) 编辑

80386的各种寄存器一览
摘要:注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早 阅读全文

posted @ 2018-02-26 10:42 AlanTu 阅读(2567) 评论(0) 推荐(0) 编辑

平衡二叉树AVL - 插入节点后旋转方法分析
摘要:平衡二叉树 AVL( 发明者为Adel'son-Vel'skii 和 Landis)是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1。 首先我们知道,当插入一个节点,从此插入点到树根节点路径上的所有节点的平衡都可能被打破,如何解决这个问题呢? 这里不讲大多数书上提的什么平衡因子,什 阅读全文

posted @ 2018-02-26 10:40 AlanTu 阅读(668) 评论(0) 推荐(0) 编辑

十种排序算法总结
摘要:首先声明一下,本文只对十种排序算法做简单总结,并参照一些资料给出自己的代码实现,并没有对某种算法理论讲解,更详细的 了解可以参考以下资料(本人参考): 1、《data structure and algorithm analysis in c 》 2、《大话数据结构》 3、http://blog.c 阅读全文

posted @ 2018-02-26 10:38 AlanTu 阅读(437) 评论(0) 推荐(0) 编辑

散列表(四)冲突处理的方法之开地址法: 二次探测再散列的实现
摘要:前面的文章分析了开地址法的其中一种:线性探测再散列,这篇文章来讲开地址法的第二种:二次探测再散列 (二)、二次探测再散列 为改善“堆积”问题,减少为完成搜索所需的平均探查次数,可使用二次探测法。 通过某一个散列函数对表项的关键码 x 进行计算,得到桶号,它是一个非负整数。 若设表的长度为TableS 阅读全文

posted @ 2018-02-26 10:35 AlanTu 阅读(15852) 评论(0) 推荐(0) 编辑

散列表(三)冲突处理的方法之开地址法: 线性探测再散列的实现
摘要:二、开地址法 基本思想:当关键码key的哈希地址H0 = hash(key)出现冲突时,以H0为基础,产生另一个哈希地址H1 ,如果H1仍然冲突,再以H0 为基础,产生另一个哈希地址H2 ,…,直到找出一个不冲突的哈希地址Hi ,将相应元素存入其中。这种方法有一个通用的再散列函 数形式: 其中H0 阅读全文

posted @ 2018-02-26 10:33 AlanTu 阅读(16170) 评论(0) 推荐(0) 编辑

散列表(二)冲突处理的方法之链地址法的实现: 哈希查找
摘要:首先需要澄清的一点是,这里讲的是hash table/hash map ,即数据项所存储的表要用数组来实现。 一、链地址法 这种基本思想:将所有哈希地址为i 的元素构成一个称为同义词链的链表,并将链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在 同义词链中进行。 该散列方法首先对关键 阅读全文

posted @ 2018-02-26 10:31 AlanTu 阅读(914) 评论(0) 推荐(0) 编辑

散列表(一)散列表概念、散列函数构造方法、常见字符串哈希函数: 测试冲突
摘要:一、散列表基本概念 1、散列表(hash table) ,也叫哈希表,是根据关键码而直接进行访问的数据结构。也就是说,它通过把关键码映射到表中一个位置 来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。 2、若结构中存在关键码为x的记录,则必定在hash(x)的存储位 阅读全文

posted @ 2018-02-26 10:30 AlanTu 阅读(1341) 评论(0) 推荐(0) 编辑

二叉排序树 - 删除节点策略及其图形化(二叉树查找)
摘要:二叉排序树(BST,Binary Sort Tree)具有这样的性质:对于二叉树中的任意节点,如果它有左子树或右子树,则该节点的数据成员大于左子树所有节点的数据成员,且小于右子树所有节点的数据成员。排序二叉树的中序遍历结果是从小到大排列的。 二叉排序树的查找和插入比较好理解,主要来看一下删除时的情况 阅读全文

posted @ 2018-02-26 10:28 AlanTu 阅读(15693) 评论(0) 推荐(0) 编辑

静态查找表 - 顺序查找、二分查找、插值查找、斐波纳契查找
摘要:查找表(Search table)是由同一类型的数据元素(或记录)构成的集合。关键字(key)是数据元素中某个数据项的值,又称为键值,用它可以表示一个数据元素,也可以标识一个记录的数据项(字段),称之为关键码。若此关键字可以唯一地标识一个记录,则称此关键字为主关键字(primary key)。而对于 阅读全文

posted @ 2018-02-26 10:27 AlanTu 阅读(550) 评论(0) 推荐(0) 编辑

AOE网与关键路径简介
摘要:前面我们说过的拓扑排序主要是为解决一个工程能否顺序进行的问题,但有时我们还需要解决工程完成需要的最短时间问题。如果我们要对一个流程图获得最短时间,就必须要分析它们的拓扑关系,并且找到当中最关键的流程,这个流程的时间就是最短时间。 在前面讲了AOV网的基础上,来介绍一个新的概念。在一个表示工程的带权有 阅读全文

posted @ 2018-02-26 10:25 AlanTu 阅读(5440) 评论(1) 推荐(0) 编辑

AOV网与拓扑排序
摘要:在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们称之为AOV网(Activity on Vextex Network)。AOV网中的弧表示活动之间存在的某种制约关系,AOV网中不能存在回路,让某个活动的开始要以自己完成作为先决条件,显然是不可 阅读全文

posted @ 2018-02-26 10:23 AlanTu 阅读(3776) 评论(1) 推荐(1) 编辑

最短路径 - 弗洛伊德(Floyd)算法
摘要:为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例。图7-7-12的左图是一个简单的3个顶点的连通网图。 我们先定义两个二维数组D[3][3]和P[3][3], D代表顶点与顶点的最短路径权值和的矩阵。P代表对应顶点的最短路径的前驱矩阵。在未分析任何顶点之前,我们将D命名为D( 阅读全文

posted @ 2018-02-26 10:20 AlanTu 阅读(649) 评论(0) 推荐(0) 编辑

最短路径 - 迪杰斯特拉(Dijkstra)算法
摘要:对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点。最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd)算法。本文先来讲第一种,从某个源点到其余各顶点的最短路径问题。 这是一个按路径长度递增的次序产生最 阅读全文

posted @ 2018-02-26 10:17 AlanTu 阅读(659) 评论(0) 推荐(0) 编辑

图解最小生成树 - 克鲁斯卡尔(Kruskal)算法
摘要:我们在前面讲过的《克里姆算法》是以某个顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树的。同样的思路,我们也可以直接就以边为目标去构建,因为权值为边上,直接找最小权值的边来构建生成树也是很自然的想法,只不过构建时要考虑是否会形成环而已,此时我们就用到了图的存储结构中的边集数组结构,如图7-6- 阅读全文

posted @ 2018-02-26 10:13 AlanTu 阅读(3129) 评论(0) 推荐(0) 编辑

图解最小生成树 - 普里姆(Prim)算法
摘要:我们在图的定义中说过,带有权值的图就是网结构。一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边。所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小。综合以上两个概念,我们可以得出:构造连通网的最小代价生成树,即最小生成树 阅读全文

posted @ 2018-02-26 10:11 AlanTu 阅读(6214) 评论(0) 推荐(0) 编辑

图 - 广度优先遍历
摘要:图的遍历和树的遍历类似,我们希望从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历(Traverse Graph)。 图的遍历方法一般有两种,第一种是我们在前面讲过的《深度优先遍历(Depth First Search)》,也有称为深度优先搜索,简称为DFS。第二 阅读全文

posted @ 2018-02-26 10:09 AlanTu 阅读(5644) 评论(0) 推荐(0) 编辑

图 - 深度优先遍历
摘要:图的遍历和树的遍历类似,我们希望从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历(Traverse Graph)。 图的遍历方法一般有两种,第一种是深度优先遍历(Depth First Search),也有称为深度优先搜索,简称为DFS。第二种是《广度优先遍历( 阅读全文

posted @ 2018-02-26 10:07 AlanTu 阅读(480) 评论(0) 推荐(0) 编辑

图 - 存储结构之邻接表
摘要:对于图来说,邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的。因此我们考虑另外一种存储结构方式:邻接表(Adjacency List),即数组与链表相结合的存储方法。 邻接表的处理方法是这样的。 1、图中顶点用一个一维数组存储,另外,对于 阅读全文

posted @ 2018-02-26 10:06 AlanTu 阅读(5471) 评论(0) 推荐(0) 编辑

图 - 存储结构之邻接矩阵
摘要:图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图。一个一维的数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 我们来看一个实例,图7-4-2的左图就是一个无向图。 我们再来看一个有向图样例 阅读全文

posted @ 2018-02-26 10:04 AlanTu 阅读(451) 评论(0) 推荐(0) 编辑

图 - 定义和术语总结
摘要:一、图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。在图中的数据元素,我们称之为顶点(Vertex),顶点集合有穷非空。在图中,任意两个顶点之间都可能有关系,顶点之间的逻辑关系用边来表示,边集可以是 阅读全文

posted @ 2018-02-26 10:03 AlanTu 阅读(316) 评论(0) 推荐(0) 编辑

线索二叉树
摘要:我们知道满二叉树只是一种特殊的二叉树,大部分二叉树的结点都是不完全存在左右孩子的,即很多指针域没有被充分地利用。另一方面我们在对一棵二叉树做某种次序遍历的时候,得到一串字符序列,遍历过后,我们可以知道结点之间的前驱后继关系,也就是说,我们可以很清楚地知道任意一个结点,它的前驱和后继是哪一个。可是这是 阅读全文

posted @ 2018-02-26 10:02 AlanTu 阅读(265) 评论(0) 推荐(0) 编辑

二叉树 - 遍历和存储结构
摘要:在《二叉树的定义和性质》中我们已经认识了二叉树这种数据结构。我们知道链表的每个节点可以有一个后继,而二叉树(Binary Tree)的每个节点可以有两个后继。比如这样定义二叉树的节点: typedef struct node *link; struct node { unsigned char it 阅读全文

posted @ 2018-02-26 10:00 AlanTu 阅读(235) 评论(0) 推荐(0) 编辑

迷宫问题 - 队列与广度优先搜索
摘要:队列也是一组元素的集合,也提供两种基本操作:Enqueue(入队)将元素添加到队尾,Dequeue(出队)从队头取出元素并返回。就像排队买票一样,先来先服务,先入队的人也是先出队的,这种方式称为FIFO(First In First Out,先进先出),有时候队列本身也被称为FIFO。 下面我们用队 阅读全文

posted @ 2018-02-26 09:59 AlanTu 阅读(1718) 评论(0) 推荐(0) 编辑

迷宫问题 - 堆栈与深度优先搜索
摘要:堆栈的访问规则被限制为Push和Pop两种操作,Push(入栈或压栈)向栈顶添加元素,Pop(出栈或弹出)则取出当前栈顶的元素,也就是说,只能访问栈顶元素而不能访问栈中其它元素。 现在我们用堆栈解决一个有意思的问题,定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0 阅读全文

posted @ 2018-02-26 09:58 AlanTu 阅读(1142) 评论(0) 推荐(0) 编辑

Solutions for the Maximum Subsequence Sum Problem
摘要:The maximum subarray problem is the task of finding the contiguous subarray within a one-dimensional array of numbers (containing at least one positiv 阅读全文

posted @ 2018-02-26 09:57 AlanTu 阅读(156) 评论(0) 推荐(0) 编辑

单链表 - 插入和删除操作
摘要:下图展示了单链表的基本结构: head指针是链表的头指针,指向第一个节点,每个节点的next指针域指向下一个节点,最后一个节点的next指针域为NULL,在图中用0表示。 下面先来看程序(栈的链式存储实现,另外一个实现点这里)和对应的输出(注意输出前进行了链表反转(见《单链表反转》,否则程序后面的w 阅读全文

posted @ 2018-02-26 09:51 AlanTu 阅读(3045) 评论(0) 推荐(0) 编辑

双向链表实现队列与循环链表
摘要:一、双向链表(double linked list)如图26.5,是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。双向链表的基本操作与单链表基本一样,除了插入和删除的时候需要更改两个指针变量,需要注意的是修改的顺序很重要,插入如图3-14-5,删除如图3-14-6。 链表的delete操作 阅读全文

posted @ 2018-02-26 09:48 AlanTu 阅读(3133) 评论(0) 推荐(0) 编辑

二叉树 - 定义和性质以及特殊二叉树
摘要:一、二叉树(Binary Tree)是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。如图1就是一棵二叉树 图1 二叉树的特点: (1)每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。 (2)左 阅读全文

posted @ 2018-02-26 09:46 AlanTu 阅读(5547) 评论(0) 推荐(0) 编辑

树 - 定义和基本概念
摘要:一、树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一棵非空树中:(1)有且仅有一个特定的称为根(root)的结点。 (2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,....,Tm, 其中每一个集合本身又是一棵树,并且称为根的子树(SubTree),如 阅读全文

posted @ 2018-02-26 09:44 AlanTu 阅读(2864) 评论(0) 推荐(0) 编辑

字符串 - KMP模式匹配
摘要:在朴素的模式匹配算法中,主串的pos值(i)是不断地回溯来完成的(见字符串的基本操作中的Index函数)。而计算机的大仙们发现这种回溯其实可以是不需要的。既然i值不回溯,也就是不可以变小,那么考虑的变化就是子串的pos值(j)了。通过分析发现子串中如果有相等字符,j值的变化就会不相同,也就是说,这个 阅读全文

posted @ 2018-02-26 09:43 AlanTu 阅读(272) 评论(0) 推荐(0) 编辑

字符串 - 基本操作
摘要:字符串(string)是由0个或多个字符组成的有限序列。一般使用顺序存储结构,末尾以'\0'表示结束,但不计入字符串的长度。 示例程序:(改编自《大话数据结构》) C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 阅读全文

posted @ 2018-02-26 09:41 AlanTu 阅读(483) 评论(0) 推荐(0) 编辑

队列 - 链式存储结构
摘要:队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们把它简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头节点,而队尾指针指向终端节点。空队列时,front和rear都指向头节点。 示例程序:(改变自《大话数据结构》) C++ Code 1 2 3 4 5 6 7 8 阅读全文

posted @ 2018-02-26 09:39 AlanTu 阅读(648) 评论(0) 推荐(0) 编辑

循环队列 - 顺序存储结构
摘要:队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。是一种先进先出的线性表(FIFO)。允许插入的一端称为队尾,允许删除的一端称为队头。我们在《栈的顺序存储结构》中发现,栈操作的top指针在Push时增大而在Pop时减小,栈空间是可以重复利用的,而队列的front、rear 阅读全文

posted @ 2018-02-26 09:37 AlanTu 阅读(1178) 评论(0) 推荐(0) 编辑

栈 - 链式存储结构
摘要:当单链表限定只能在头部进行插入和删除操作的时候,即为链栈,一般我们会将单链表的头指针和栈的栈顶指针top合二为一,通常对链栈来说,是不需要头节点的,因为我们维护了栈顶指针。对于链栈来说,基本不存在栈满的情况,除非内存已经没有可以使用的空间,对于空栈来说,链表原定义是头指针指向空,那么链栈的空其实就是 阅读全文

posted @ 2018-02-26 09:34 AlanTu 阅读(421) 评论(0) 推荐(0) 编辑

栈 - 顺序存储结构
摘要:栈(stack)是限定在表尾进行插入和删除操作的线性表。我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom) ,栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。 示例程序:(改编自《大话数据结构》) C++ Code 1 2 3 4 5 6 阅读全文

posted @ 2018-02-26 09:32 AlanTu 阅读(236) 评论(0) 推荐(0) 编辑

两栈共享存储空间
摘要:数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈为栈的末端,即下标为数组长度 n-1处。这样,如果两个栈增加元素,就是两端点向中间延伸。当top1 + 1 == top2 的时候为栈满。 示例代码:(改编自《大话数据结构》) C++ Code 1 2 3 4 5 阅读全文

posted @ 2018-02-26 09:32 AlanTu 阅读(418) 评论(0) 推荐(0) 编辑

静态链表
摘要:首先我们让数组的元素都是由两个数据域组成,data和cur。也就是说,数组的每一个下标都对应一个data和一个cur。 数据域data用来存放数据元素,也就是通常我们要处理的数据;而游标cur相当于单链表中的next指针, 存放该元素的后继在数组中的下标。我们把这种用数组描述的链表叫做静态链表。 数 阅读全文

posted @ 2018-02-26 09:30 AlanTu 阅读(5658) 评论(0) 推荐(2) 编辑

线性表 - 链式存储结构
摘要:为了表示每个数据元素ai与其直接后继元素ai+1之间的逻辑关系,对数据ai,除了存储其自身的信息之外,还需存储一个指示其 直接后继的信息(即直接后继的存储位置)。这两部分信息组成数据元素ai的存储映像,称为结点(Node)。N个结点链结成一个链表, 即为线性表(a1,a2,...,an)的链式存储结 阅读全文

posted @ 2018-02-26 09:29 AlanTu 阅读(254) 评论(0) 推荐(0) 编辑

线性表 - 顺序存储结构
摘要:线性表的数据对象集合为 {a1,a2,....an},每个元素的类型均为Datatype。其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。 线性表的顺序存储结构的优缺点: 优点:无须为表示表中 阅读全文

posted @ 2018-02-26 09:28 AlanTu 阅读(176) 评论(0) 推荐(0) 编辑

快速排序以及第k小元素的线性选择算法
摘要:简要介绍下快速排序的思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。时间复杂度为O(nlogn) 一.《data structure and 阅读全文

posted @ 2018-02-26 09:27 AlanTu 阅读(1736) 评论(0) 推荐(0) 编辑

虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?
摘要:五条基本规则: 1、如果基类已经插入了vptr, 则派生类将继承和重用该vptr。vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的。 2、在遇到通过基类指针或引用调用虚函数的语句时,首先根据指针或引用的静态类型来判断所调函数是否属 阅读全文

posted @ 2018-02-26 09:19 AlanTu 阅读(900) 评论(1) 推荐(0) 编辑

详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
摘要:一、boost 智能指针 智能指针是利用RAII(Resource Acquisition Is Initialization:资源获取即初始化)来管理资源。关于RAII的讨论可以参考前面的文章。在使用boost库之前应该先下载后放在某个路径,并在VS 包含目录中添加。下面是boost 库里面的智能 阅读全文

posted @ 2018-02-26 09:13 AlanTu 阅读(835) 评论(0) 推荐(0) 编辑

容器适配器(stack、 queue 、priority_queue)源码浅析与使用示例
摘要:一、容器适配器 stack queue priority_queue stack、queue、priority_queue 都不支持任一种迭代器,它们都是容器适配器类型,stack是用vector/deque/list对象创建了一个先进后出容器;queue是用deque或list对象创建了一个先进先 阅读全文

posted @ 2018-02-26 09:09 AlanTu 阅读(326) 评论(0) 推荐(0) 编辑

迭代器适配器{(插入迭代器back_insert_iterator)、IO流迭代器(istream_iterator、ostream_iterator)}
摘要:一、迭代器适配器 反向迭代器 插入迭代器 IO流迭代器 其中反向迭代器可以参考以前的文章。 二、插入迭代器 插入迭代器实际上是一个输出迭代器(*it=; ++) back_insert_iterator back_inserter front_insert_iterator front_insert 阅读全文

posted @ 2018-02-26 09:07 AlanTu 阅读(1620) 评论(0) 推荐(0) 编辑

函数适配器bind2nd 、mem_fun_ref 源码分析、函数适配器应用举例
摘要:一、适配器 三种类型的适配器: 容器适配器:用来扩展7种基本容器,利用基本容器扩展形成了栈、队列和优先级队列 迭代器适配器:(反向迭代器、插入迭代器、IO流迭代器) 函数适配器:函数适配器能够将仿函数和另一个仿函数(或某个值、或某个一般函数)结合起来。 针对成员函数的函数适配器 针对一般函数的函数适 阅读全文

posted @ 2018-02-26 09:03 AlanTu 阅读(238) 评论(0) 推荐(0) 编辑

函数对象、 函数对象与容器、函数对象与算法
摘要:一、函数对象 1、函数对象(function object)也称为仿函数(functor) 2、一个行为类似函数的对象,它可以没有参数,也可以带有若干参数。 3、任何重载了调用运算符operator()的类的对象都满足函数对象的特征 4、函数对象可以把它称之为smart function。 5、ST 阅读全文

posted @ 2018-02-26 08:57 AlanTu 阅读(324) 评论(0) 推荐(0) 编辑

剩下5种算法代码分析与使用示例(remove 、rotate 、sort、lower_bound、accumulate)
摘要:一、移除性算法 (remove) C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 4 阅读全文

posted @ 2018-02-26 08:55 AlanTu 阅读(329) 评论(0) 推荐(0) 编辑

变动性算法源代码分析与使用示例(copy_backward、 transform、 replace_copy_if 等)
摘要:首先回顾前面的文章,我们把for_each 归类为非变动性算法,实际上它也可以算是变动性算法,取决于传入的第三个参数,即函数 指针。如果在函数内对容器元素做了修改,那么就属于变动性算法。 变动性算法源代码分析与使用示例: 一、copy、copy_backward C++ Code 1 2 3 4 5 阅读全文

posted @ 2018-02-26 08:53 AlanTu 阅读(403) 评论(0) 推荐(0) 编辑

非变动性算法源代码分析与使用示例( for_each、min_element 、find_if、search 等)
摘要:非变动性算法代码分析与示例: 一、for_each C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // TEMPLATE FUNCTION for_each template < class _InIt, class _Fn1 > inline _Fn1 for 阅读全文

posted @ 2018-02-26 08:51 AlanTu 阅读(303) 评论(0) 推荐(0) 编辑

迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
摘要:一、迭代器 迭代器是泛型指针 普通指针可以指向内存中的一个地址 迭代器可以指向容器中的一个位置 STL的每一个容器类模版中,都定义了一组对应的迭代器类。使用迭代器,算法函数可以访问容器中指定位置的元素,而无需关心元素的具体类型。 下面来稍微看一下vector<class>::iterator 和 v 阅读全文

posted @ 2018-02-26 08:49 AlanTu 阅读(2137) 评论(0) 推荐(0) 编辑

算法简介、7种算法分类
摘要:一、算法 算法是以函数模板的形式实现的。常用的算法涉及到比较、交换、查找、搜索、复制、修改、移除、反转、排序、合并等等。 算法并非容器类型的成员函数,而是一些全局函数,要与迭代器一起搭配使用。 算法的优势在于只需实作一份,可以适应所有的容器,不必为每一种容器量订制。也可以与用户定义的容器搭配。 算法 阅读全文

posted @ 2018-02-26 08:49 AlanTu 阅读(4848) 评论(0) 推荐(0) 编辑

实现简单容器模板类Vec(vector capacity 增长问题、allocator 内存分配器)
摘要:首先,vector 在VC 2008 中的实现比较复杂,虽然vector 的声明跟VC6.0 是一致的,如下: C++ Code 1 2 template < class _Ty, class _Ax = allocator<_Ty> > class vector; 但在VC2008 中vector 阅读全文

posted @ 2018-02-26 08:47 AlanTu 阅读(806) 评论(0) 推荐(0) 编辑

STL六大组件简介
摘要:一、STL简介 (一)、泛型程序设计 泛型编程(generic programming) 将程序写得尽可能通用 将算法从数据结构中抽象出来,成为通用的 C++的模板为泛型程序设计奠定了关键的基础 (二)、什么是STL 1、STL(Standard Template Library),即标准模板库,是 阅读全文

posted @ 2018-02-26 08:44 AlanTu 阅读(1956) 评论(0) 推荐(0) 编辑

用模板实现单例模式(线程安全)、模板方式实现动态创建对象
摘要:一、用模板实现单例模式 在前面的文章中,用过多种方法实现单例模式,现在用模板方式来实现: 为了实现线程安全,需要在linux 下使用pthread_mutex_t 加锁,请使用g++ 编译并需要链接 -lpthread 使用的是double-check lock, 指针instance_ 最好声明为 阅读全文

posted @ 2018-02-26 08:43 AlanTu 阅读(999) 评论(0) 推荐(0) 编辑

缺省模板参数(借助标准模板容器实现Stack模板)、成员模板、关键字typename
摘要:一、缺省模板参数 回顾前面的文章,都是自己管理stack的内存,无论是链栈还是数组栈,能否借助标准模板容器管理呢?答案是肯定的,只需要多传一个模板参数即可,而且模板参数还可以是缺省的,如下: template <typename T, typename CONT = std::deque<T> > 阅读全文

posted @ 2018-02-26 08:42 AlanTu 阅读(357) 评论(0) 推荐(0) 编辑

类模板、Stack的类模板实现(自定义链栈方式,自定义数组方式)
摘要:一、类模板 类模板:将类定义中的数据类型参数化 类模板实际上是函数模板的推广,可以用相同的类模板来组建任意类型的对象集合 (一)、类模板的定义 template <类型形参表> class <类名> { //类说明体 }; template <类型形参表> <返回类型> <类名> <类型名表>::< 阅读全文

posted @ 2018-02-25 23:39 AlanTu 阅读(1044) 评论(0) 推荐(0) 编辑

函数模板、函数模板特化、重载函数模板、非模板函数重载
摘要:一、引子 考虑求两数较大值函数max(a,b) 对于a,b的不同类型,都有相同的处理形式: return a < b ? b : a; 用已有方法解决: (1)宏替换 #define max(a,b) ((a)< (b) ? (b) : (a)) 存在的问题:避开类型检查 (2)重载 存在的问题:需 阅读全文

posted @ 2018-02-25 23:38 AlanTu 阅读(919) 评论(0) 推荐(0) 编辑

输出流格式化(以操纵子方式格式化,以ios类成员函数方式格式化)
摘要:一、以操纵子方式格式化 数据输入输出的格式控制使用系统头文件<iomanip>中提供的操纵符。把它们作为插入操作符<<的输出对象即可。如setiosflags、setw、setfill、setprecision、hex、oct等。 (一)、常用的流操纵算子: (二)、ios类的枚举常量 C++ Co 阅读全文

posted @ 2018-02-25 23:36 AlanTu 阅读(648) 评论(0) 推荐(0) 编辑

文件的读写、二进制文件的读写、文件随机读写
摘要:一、文件的读写 如前面所提,流的读写主要有<<, >>, get, put, read, write 等操作,ofstream 继承自ostream, ifstream 继承自 istream,故操作函数都是一致的。 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 阅读全文

posted @ 2018-02-25 23:35 AlanTu 阅读(2948) 评论(0) 推荐(0) 编辑

文件流(fstream, ifstream, ofstream)的打开关闭、流状态
摘要:一、文件流 ofstream,由ostream派生而来,用于写文件 ifstream,由istream派生而来, 用于读文件 fstream,由iostream派生而来,用于读写文件 二、打开文件 说明了流对象之后,可使用函数open()打开文件。文件的打开即是在流与文件之间建立一个连接 函数原型 阅读全文

posted @ 2018-02-25 23:34 AlanTu 阅读(13208) 评论(0) 推荐(0) 编辑

流类库继承体系(IO流,文件流,串流)和 字符串流的基本操作
摘要:一、IO、流 数据的输入和输出(input/output简写为I/O) 对标准输入设备和标准输出设备的输入输出简称为标准I/O 对在外存磁盘上文件的输入输出简称为文件I/O 对内存中指定的字符串存储空间的输入输出简称为串I/O 数据输入输出的过程,可以形象地看成流 从流中获取数据的操作称为“提取”( 阅读全文

posted @ 2018-02-25 23:32 AlanTu 阅读(670) 评论(0) 推荐(0) 编辑

对象语义与值语义、资源管理(RAII、资源所有权)、模拟实现auto_ptr<class>、实现Ptr_vector
摘要:一、对象语义与值语义 1、值语义是指对象的拷贝与原对象无关。拷贝之后就与原对象脱离关系,彼此独立互不影响(深拷贝)。比如说int,C++中的内置类型都是值语义,前面学过的三个标准库类型string,vector,map也是值语义 2、对象语义指的是面向对象意义下的对象 对象拷贝是禁止的(Noncop 阅读全文

posted @ 2018-02-25 23:31 AlanTu 阅读(359) 评论(0) 推荐(0) 编辑

operator new 和 operator delete 实现一个简单内存泄漏跟踪器
摘要:先来说下实现思路:可以实现一个Trace类,调用 operator new 的时候就将指向分配内存的指针、当前文件、当前行等信息添加进Trace 成员map容器内,在调用operator delete 的时候删除这些信息。定义一个全局Trace 对象,当程序结束,对象析构时判断成员map 是否还有信 阅读全文

posted @ 2018-02-25 23:28 AlanTu 阅读(361) 评论(0) 推荐(0) 编辑

异常与继承、异常与指针、异常规格说明
摘要:一、异常与继承 如果异常类型为C++的类,并且该类有其基类,则应该将派生类的错误处理程序放在前面,基类的错误处理程序放在后面 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 阅读全文

posted @ 2018-02-25 23:26 AlanTu 阅读(475) 评论(0) 推荐(0) 编辑

程序错误、异常(语法、抛出、捕获、传播)、栈展开
摘要:一、程序错误 编译错误,即语法错误。程序就无法被生成运行代码。 运行时错误 不可预料的逻辑错误 可以预料的运行异常 例如: 动态分配空间时可能不会成功 打开文件可能会失败 除法运算时分母可能为0 整数相乘可能溢出 数组越界…… 二、异常 (一)、异常语法 throw 表达式; try { //try 阅读全文

posted @ 2018-02-25 23:25 AlanTu 阅读(1079) 评论(0) 推荐(0) 编辑

C语言错误处理方法、C++异常处理方法(throw, try, catch)简介
摘要:一、C语言错误处理方法 1、返回值(if … else语句判断错误) 2、errno(linux 系统调用) 3、goto语句(函数内局部跳转) 4、setjmp、longjmp(Do not use setjmp and longjmp in C++ programs; these functio 阅读全文

posted @ 2018-02-25 23:24 AlanTu 阅读(3826) 评论(0) 推荐(0) 编辑

RTTI、dynamic_cast、typeid、类与类之间的关系uml
摘要:一、RTTI Run-time type information (RTTI) is a mechanism that allows the type of an object to be determined during program execution. There are three ma 阅读全文

posted @ 2018-02-25 23:22 AlanTu 阅读(365) 评论(0) 推荐(0) 编辑

动态创建对象
摘要:回顾前面的文章,实现了一个简单工厂模式来创建不同类对象,但由于c++没有类似new "Circle"之类的语法,导致数中需要不断地ifelse地去判断,如果有多个不同类对象需要创建,显然这是很费神的,下面通过宏定义注册的方法来实现动态创建对象 C++ Code 1 2 3 4 5 6 7 8 9 1 阅读全文

posted @ 2018-02-25 23:21 AlanTu 阅读(1757) 评论(0) 推荐(0) 编辑

对C++对象内存模型造成的影响(类/对象的大小)
摘要:首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n)所指定的值)的整数倍。 整个结构体也要对齐,结构体总大小对齐至各个min中最大值的整数倍。 win3 阅读全文

posted @ 2018-02-25 23:18 AlanTu 阅读(480) 评论(0) 推荐(0) 编辑

多重继承、虚继承与虚基类
摘要:一、多重继承 单重继承——一个派生类最多只能有一个基类 多重继承——一个派生类可以有多个基类 class 类名: 继承方式 基类1,继承方式 基类2,…. {….}; 派生类同时继承多个基类的成员,更好的软件重用 可能会有大量的二义性,多个基类中可能包含同名变量或函数 多重继承中解决访问歧义的方法: 阅读全文

posted @ 2018-02-25 23:11 AlanTu 阅读(2008) 评论(0) 推荐(1) 编辑

继承与构造函数、派生类到基类的转换
摘要:一、不能自动继承的成员函数 构造函数(包括拷贝构造函数) 析构函数 =运算符 二、继承与构造函数 基类的构造函数不被继承,派生类中需要声明自己的构造函数。 声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化调用基类构造函数完成(如果没有给出则默认调用默认构造函数)。 派生类 阅读全文

posted @ 2018-02-25 23:09 AlanTu 阅读(961) 评论(0) 推荐(0) 编辑

公有/私有/保护继承、overload/overwrite/override之间的区别
摘要:一、继承 C++很重要的一个特征就是代码重用。在C语言中重用代码的方式就是拷贝代码、修改代码。C++可以用继承或组合的方式来重用。通过组合或继承现有的的类来创建新类,而不是重新创建它们。 继承是使用已经编写好的类来创建新类,新的类具有原有类的所有属性和操作,也可以在原有类的基础上作一些修改和增补。 阅读全文

posted @ 2018-02-25 23:08 AlanTu 阅读(659) 评论(0) 推荐(0) 编辑

map 类简介和例程
摘要:一、标准库的map类型 使用map得包含map类所在的头文件 template < class Key, class Type, class Traits = less<Key>, class Allocator=allocator<pair <const Key, Type> > > class 阅读全文

posted @ 2018-02-25 23:06 AlanTu 阅读(198) 评论(0) 推荐(0) 编辑

vector 类简介和例程
摘要:一、标准库的vector类型 vector是同一种类型的对象的集合 vector的数据结构很像数组,能非常高效和方便地访问单个元素 vector是一个类模板(class template) vector不能存放引用。 template < class Type, class Allocator = 阅读全文

posted @ 2018-02-25 23:04 AlanTu 阅读(442) 评论(0) 推荐(0) 编辑

string 类简介和例程
摘要:一、标准库string类型 string类型支持长度可变的字符串,C++标准库将负责管理与存储字符相关的内存,以及提供各种有用的操作 ,在VC中直接F1查看 template < class CharType, class Traits=char_traits<CharType>, class Al 阅读全文

posted @ 2018-02-25 23:03 AlanTu 阅读(475) 评论(0) 推荐(0) 编辑

类型转换运算符、*运算符重载、->运算符重载、operator new 和 operator delete
摘要:一、类型转换运算符 必须是成员函数,不能是友元函数 没有参数 不能指定返回类型 函数原型:operator 类型名(); C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #ifndef _INTEGER_H_ 阅读全文

posted @ 2018-02-25 23:01 AlanTu 阅读(385) 评论(0) 推荐(0) 编辑

完善String类([]、 +、 += 运算符重载)、>>和<<运算符重载
摘要:在前面文章中使用过几次String类的例子,现在多重载几个运算符,更加完善一下,并且重载流类运算符。 []运算符重载 +运算符重载 +=运算符重载 <<运算符重载 >>运算符重载 String.h: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 阅读全文

posted @ 2018-02-25 23:00 AlanTu 阅读(7639) 评论(0) 推荐(1) 编辑

++运算符重载、!运算符重载、赋值运算符重载
摘要:一、++运算符重载 前置++运算符重载 成员函数的方式重载,原型为: 函数类型 & operator++(); 友元函数的方式重载,原型为: friend 函数类型 & operator++(类类型 &); 后置++运算符重载 成员函数的方式重载,原型为: 函数类型 operator++(int); 阅读全文

posted @ 2018-02-25 22:59 AlanTu 阅读(452) 评论(0) 推荐(0) 编辑

以成员函数方式重载、以友元函数方式重载
摘要:一、运算符重载 运算符重载允许把标准运算符(如+、-、*、/、<、>等)应用于自定义数据类型的对象 直观自然,可以提高程序的可读性 体现了C++的可扩充性 运算符重载仅仅只是语法上的方便,它是另一种函数调用的方式 运算符重载,本质上是函数重载 不要滥用重载、因为它只是语法上的方便,所以只有在涉及的代 阅读全文

posted @ 2018-02-25 22:57 AlanTu 阅读(3133) 评论(0) 推荐(0) 编辑

友元函数和友元类
摘要:一、友元介绍 我们知道,类的成员函数可以访问同类的其他成员函数,包括公有、私有和保护成员。而类的外部函数只能访问类的公有成员。 友元是一种允许非类成员函数访问类的非公有成员的一种机制。 可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元。 友元函数 友元类 二、友元函数 友元函数在类作 阅读全文

posted @ 2018-02-25 22:56 AlanTu 阅读(1121) 评论(0) 推荐(0) 编辑

分别用C和C++来实现一个链栈
摘要:下面通过分别用C和C++来实现一个链栈(链表实现),从中体会数据封装抽象的思想: C语言实现: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 阅读全文

posted @ 2018-02-25 22:54 AlanTu 阅读(392) 评论(0) 推荐(0) 编辑

static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符
摘要:一、static 与单例模式 单例模式也就是简单的一种设计模式,它需要: 保证一个类只有一个实例,并提供一个全局访问点 禁止拷贝 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 2 阅读全文

posted @ 2018-02-25 22:53 AlanTu 阅读(367) 评论(0) 推荐(0) 编辑

四种对象生存期和作用域、static 用法总结
摘要:一、四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象、静态全局对象 全局对象的构造先于main函数 已初始化的全局变量或静态全局对象存储于.data段中 未初始化的全局变量或静态全局对象存储于.bss段中 静 阅读全文

posted @ 2018-02-25 22:51 AlanTu 阅读(1214) 评论(0) 推荐(0) 编辑

static 成员变量、static 成员函数、类/对象的大小
摘要:一、static 成员变量 对于特定类型的全体对象而言,有时候可能需要访问一个全局的变量。比如说统计某种类型对象已创建的数量。 如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个全局变量,这时可以用类的静态成员来解决这个问题。 非static数据成员存在于类类型的每个对象中,stati 阅读全文

posted @ 2018-02-25 22:50 AlanTu 阅读(1871) 评论(0) 推荐(0) 编辑

深拷贝与浅拷贝、空类与空数组
摘要:一、深拷贝与浅拷贝 说得简单点,假设一个类有指针成员,如果在拷贝的时候顺带连指针指向的内存也分配了,就称为深拷贝,如下图(v2 从 v 拷贝而来): 如果只是分配指针本身的内存,那就是浅拷贝,如下图: 浅拷贝造成的问题是有两个指针指向同块内存,delete 其中一个指针,那么剩下的指针将成为野指针。 阅读全文

posted @ 2018-02-25 22:48 AlanTu 阅读(506) 评论(0) 推荐(0) 编辑

初始化列表(const和引用成员)、拷贝构造函数
摘要:一、构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化段 普通计算段 (一)、对象成员及其初始化 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 阅读全文

posted @ 2018-02-25 22:47 AlanTu 阅读(2813) 评论(0) 推荐(0) 编辑

构造函数、析构函数、赋值与初始化、explicit关键字
摘要:一、构造函数、默认构造函数 (1)、构造函数 构造函数是特殊的成员函数 创建类类型的新对象,系统自动会调用构造函数 构造函数是为了保证对象的每个数据成员都被正确初始化 函数名和类名完全相同 不能定义构造函数的类型(返回类型),也不能使用void 通常情况下构造函数应声明为公有函数,一般被隐式地调用。 阅读全文

posted @ 2018-02-25 22:44 AlanTu 阅读(799) 评论(0) 推荐(0) 编辑

类声明、类作用域、前向声明、this指针、嵌套类、PIMPL 技法 等
摘要:一、类声明 //类是一种用户自定义类型,声明形式: class 类名称 { public: 公有成员(外部接口) private: 私有成员 protected: 保护成员 }; 在关键字public后面声明,它们是类与外部的接口,任何外部函数都可以访问公有类型数据和函数。 在关键字private后 阅读全文

posted @ 2018-02-25 22:43 AlanTu 阅读(386) 评论(0) 推荐(0) 编辑

引用、数组引用与指针引用、内联函数inline、四种类型转换运算符
摘要:一、引用 (1)、引用是给一个变量起别名 定义引用的一般格式:类型 &引用名 = 变量名; 例如:int a=1; int &b=a;// b是a的别名,因此a和b是同一个单元 注意:定义引用时一定要初始化,指明该引用是谁的别名 在实际应用中,引用一般用作参数传递与返回值 引用不是变量,引用仅仅只是 阅读全文

posted @ 2018-02-25 22:41 AlanTu 阅读(561) 评论(0) 推荐(0) 编辑

const与#define、结构体对齐、函数重载name mangling、new/delete 等
摘要:一、bool 类型 逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC++中为1个字节。 声明方式:bool result; result=true; 可以当作整数用(true一般为1,false为0) 把其它类型的值转换为布尔值时,非零 阅读全文

posted @ 2018-02-25 22:39 AlanTu 阅读(289) 评论(0) 推荐(0) 编辑

实现一些字符串操作标准库函数、解决一些字符串问题
摘要:一、实现字符串操作标准库函数 (1)、strcpy、strncpy、memmove、memcpy、memset、strlen、strncat 的实现 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 阅读全文

posted @ 2018-02-25 22:36 AlanTu 阅读(658) 评论(0) 推荐(0) 编辑

windows下LIB和DLL的区别与使用
摘要:共有两种库: 一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。 一种是LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。 阅读全文

posted @ 2018-02-25 22:34 AlanTu 阅读(9785) 评论(1) 推荐(2) 编辑

C++模板类内友元(友元函数,友元类)声明的三种情况
摘要:根据《C++ Primer》第三版16.4节的叙述,C++类模板友元分为以下几种情况 1.非模板友元类或友元函数。 书上给了一个例子: class Foo{ void bar(); }; template <class T> class QueueItem{ friend class foobar; 阅读全文

posted @ 2018-02-25 22:31 AlanTu 阅读(3667) 评论(0) 推荐(0) 编辑

字符编解码的故事(ASCII,GBK,Unicode,Utf-8区别)
摘要:很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们认为8个开关状态作为原子单位很好,于是他们把这称为"字节"。 再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出更多的状态,状态开始变来变去。他们看到这样是好的,于是它们就这机 阅读全文

posted @ 2018-02-25 22:30 AlanTu 阅读(345) 评论(0) 推荐(0) 编辑

C++中四种类型转换以及const_cast是否能改变常量的问题
摘要:we have four specific casting operators:dynamic_cast, reinterpret_cast, static_cast and const_cast. Their format is to follow the new type enclosed be 阅读全文

posted @ 2018-02-25 22:28 AlanTu 阅读(3267) 评论(0) 推荐(1) 编辑

预处理、编译和运行的区别
摘要:相信很多人懂这个问题,也很多人没想过,包括我,今天看书想到了就写下来。先看程序(抱歉在linux下没有找到舒服的可以复制terminal的工具,只好截图了,将就着看看) 注释的就先不看了,看那几行没有注释的enum coordinate_type 表示一个枚举(Enumeration)类型。枚举类型 阅读全文

posted @ 2018-02-25 22:23 AlanTu 阅读(2355) 评论(0) 推荐(0) 编辑

C++的引用与const指针的关系以及各种传递方式
摘要:首先我们知道 const int *p 与 int const *p 是一样的,即 *p 是常量;而 int * const p 跟上面是不一样的,即 p 是常量;我们知道引用只是一个别名,与变量共享存储空间,并且必须在定义的时候初始化,而且不能再成为别的变量的别名,这让我们想到什么呢,貌似跟 in 阅读全文

posted @ 2018-02-25 22:18 AlanTu 阅读(870) 评论(0) 推荐(0) 编辑

比较显式调用构造函数和析构函数
摘要:1.首先看如下的代码,显式调用析构函数: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> using namespace std 阅读全文

posted @ 2018-02-25 22:09 AlanTu 阅读(616) 评论(0) 推荐(0) 编辑

Linux 最新SO_REUSEPORT特性
摘要:1、前言 昨天总结了一下Linux下网络编程“惊群”现象,给出Nginx处理惊群的方法,使用互斥锁。为例发挥多核的优势,目前常见的网络编程模型就是多进程或多线程,根据accpet的位置,分为如下场景: (1)单进程或线程创建socket,并进行listen和accept,接收到连接后创建进程和线程处 阅读全文

posted @ 2018-02-25 15:35 AlanTu 阅读(4501) 评论(0) 推荐(0) 编辑

Linux网络编程“惊群”问题总结
摘要:1、前言 我从事Linux系统下网络开发将近4年了,经常还是遇到一些问题,只是知其然而不知其所以然,有时候和其他人交流,搞得非常尴尬。如今计算机都是多核了,网络编程框架也逐步丰富多了,我所知道的有多进程、多线程、异步事件驱动常用的三种模型。最经典的模型就是Nginx中所用的Master-Worker 阅读全文

posted @ 2018-02-25 15:31 AlanTu 阅读(717) 评论(0) 推荐(0) 编辑

Linux下connect超时处理
摘要:1、前言 最近在写一个测试工具,要求快速的高效率的扫描出各个服务器开放了哪些端口。当时想了一下,ping只能检测ip,判断服务器的网络是连通的,而不能判断是否开放了端口。我们知道端口属于网络的传输层,因此需要用ip和端口来探测,这个时候就可以用connect来探测一下,针对TCP协议,connect 阅读全文

posted @ 2018-02-25 15:25 AlanTu 阅读(7115) 评论(0) 推荐(0) 编辑

TCP与UDP在socket编程中的区别
摘要:一、TCP与UDP的区别 基于连接与无连接 对系统资源的要求(TCP较多,UDP少) UDP程序结构较简单 流模式与数据报模式 TCP保证数据正确性,UDP可能丢包 TCP保证数据顺序,UDP不保证 部分满足以下几点要求时,应该采用UDP 面向数据报方式 网络数据大多为短消息 拥有大量Client 阅读全文

posted @ 2018-02-25 15:22 AlanTu 阅读(292) 评论(0) 推荐(0) 编辑

select、poll、epoll之间的区别
摘要:select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说 阅读全文

posted @ 2018-02-25 15:17 AlanTu 阅读(2140) 评论(0) 推荐(0) 编辑

IO多路复用之epoll
摘要:1、基本知识 epoll是在2.6内核中提出的,是之前的select和poll的增强版本。相对于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次 阅读全文

posted @ 2018-02-25 15:00 AlanTu 阅读(1024) 评论(0) 推荐(0) 编辑

IO多路复用之poll
摘要:1、基本知识 poll的机制与select类似,与select在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制。poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文 阅读全文

posted @ 2018-02-25 14:56 AlanTu 阅读(331) 评论(0) 推荐(0) 编辑

IO多路复用之select
摘要:1、基本概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。IO多路复用适用如下场合: (1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。 (2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。 (3)如果一个TC 阅读全文

posted @ 2018-02-25 14:54 AlanTu 阅读(438) 评论(0) 推荐(0) 编辑

并发无锁队列
摘要:并发无锁队列学习之一【开篇】 1、前言 队列在计算机中非常重要的一种数据结构,尤其在操作系统中。队列典型的特征是先进先出(FIFO),符合流水线业务流程。在进程间通信、网络通信之间经常采用队列做缓存,缓解数据处理压力。结合自己在工作中遇到的队列问题,总结一下对不同场景下的队列实现。根据操作队列的场景 阅读全文

posted @ 2018-02-25 13:13 AlanTu 阅读(25574) 评论(0) 推荐(1) 编辑

《算法导论》读书笔记(七)
摘要:《算法导论》读书笔记之第16章 贪心算法—活动选择问题 前言:贪心算法也是用来解决最优化问题,将一个问题分成子问题,在现在子问题最优解的时,选择当前看起来是最优的解,期望通过所做的局部最优选择来产生一个全局最优解。书中先从活动选择问题来引入贪心算法,分别采用动态规划方法和贪心算法进行分析。本篇笔记给 阅读全文

posted @ 2018-02-25 13:05 AlanTu 阅读(412) 评论(0) 推荐(0) 编辑

《算法导论》读书笔记(六)
摘要:《算法导论》读书笔记之第15章 动态规划—装配线调度 前言:动态规划的概念 动态规划(dynamic programming)是通过组合子问题的解而解决整个问题的。分治算法是指将问题划分为一些独立的子问题,递归的求解各个问题,然后合并子问题的解而得到原问题的解。例如归并排序,快速排序都是采用分治算法 阅读全文

posted @ 2018-02-25 13:02 AlanTu 阅读(308) 评论(0) 推荐(0) 编辑

数组的连续最大子段和
摘要:问题描述:输入是一个大小为n的整型数组,要求输出数组的任何连续子数组中的最大值。例如:输入的数组为array[10] = {31,-41,59,26,-53,58,97,-93,-23,84};输出最大连续子数组和为array[2...6]:187 算法1:对所有满足0<=i<=j<=n的(i,j) 阅读全文

posted @ 2018-02-25 12:56 AlanTu 阅读(379) 评论(0) 推荐(0) 编辑

《算法导论》读书笔记(五)
摘要:《算法导论》读书笔记之第12章 二叉查找树 摘要: 本章介绍了二叉查找树的概念及操作。主要内容包括二叉查找树的性质,如何在二叉查找树中查找最大值、最小值和给定的值,如何找出某一个元素的前驱和后继,如何在二叉查找树中进行插入和删除操作。在二叉查找树上执行这些基本操作的时间与树的高度成正比,一棵随机构造 阅读全文

posted @ 2018-02-25 12:55 AlanTu 阅读(387) 评论(0) 推荐(0) 编辑

《算法导论》读书笔记(四)
摘要:《算法导论》读书笔记之第10章 基本数据结构 摘要 本章介绍了几种基本的数据结构,包括栈、队列、链表以及有根树,讨论了使用指针的简单数据结构来表示动态集合。本章的内容对于学过数据结构的人来说,没有什么难处,简单的总结一下。 1、栈和队列 栈和队列都是动态集合,元素的出入是规定好的。栈规定元素是先进后 阅读全文

posted @ 2018-02-25 12:38 AlanTu 阅读(379) 评论(0) 推荐(0) 编辑

《算法导论》读书笔记(三)
摘要:《算法导论》读书笔记之第7章 快速排序 本章介绍了快速排序及其算法分析,快速排序采用的是分治算法思想,对包含n个数的输入数组,最坏情况下运行时间为θ(n^2),但是平均性能相当好,期望的运行时间为θ(nlgn)。另外快速排序能够就地排序(我理解是不需要引入额外的辅助空间,每次划分能确定一个元素的具体 阅读全文

posted @ 2018-02-25 12:29 AlanTu 阅读(361) 评论(0) 推荐(0) 编辑

导航