自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(50)
  • 资源 (1)
  • 收藏
  • 关注

原创 知识梳理------线程同步

一、为什么要线程同步 当多个控制线程共享相同的内存时,需要每个线程看到一致的数据视图。 共享资源,多个线程都可对共享资源操作 线程操作共享资源的先后顺序不确定 处理器对存储器的操作一般不是原子操作 二、互斥量 <1> 互斥量从本质上说是一把锁,在访问共享资源前对互斥量进行加锁,下访问完成后释放互斥量上的锁。对互斥量加锁之后,任何视图再次对互斥量加锁的线程都将被阻塞,直到给

2016-09-10 17:59:44 279

原创 知识梳理------线程

一、 线程的概念 <1> 进程与线程的关系线程是轻量级进程,也有PCB。创建线程使用的底层函数和进程一样,都是clone().从内核来看,进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存资源的三级页表是相同的。进程可以蜕变为线程在linux中,进程是资源分配的最小单位,线程是最小的执行单位。<2> 线程间共享的资源文件描述符表每种信号的处理方式当前工作目录用户ID和

2016-09-08 11:44:45 250

原创 知识梳理------进程(三)

进程间通信续 <5> 信号量(Posix) 信号量是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语。 包括:Posix有名信号量。使用Posix IPC名字标识,可用于进程或线程间的同步。Posix基于内存的信号量。存放在共享内存区,可用于进程或线程间的同步。System v信号量。在内核中维护,可用于进程或线程间的同步。Posix信号量可以不必在内核中维护。另外,Po

2016-09-06 21:22:32 340

原创 I/O复用------epoll

<1> 内核事件表 epoll是Linux特有的I/O复用函数,在实现和使用上与poll和selec有所不同。首先,epoll使用一组函数来完成任务,而非单个函数epoll把用户关心的文件描述符上的事件放在内核的一个事件表中,从而无需像select和poll那样每次调用都要从新传入描述符集或事件集。1) epoll_create 创建一个额外的文件描述符,来唯一标识

2016-09-03 18:27:19 248

原创 知识梳理------进程(二)

一、进程间通信 每个进程都有各自不同的用户地址空间,任何一个进程得 全局变量在另一个进程中都是不可见的,即进程之间要交换数据必须要通过内核。(在内核中开辟一块缓冲区,进程A把数据从用户空间拷贝到内核空间缓冲区中,进程B在从内核缓冲区中把数据读走)<1> pipe管道 (使用队列实现,一般时环形队列,默认阻塞) 管道是一种基本的IPC机制,实现就是在内核中开辟缓冲区。

2016-09-01 11:48:28 261

原创 I/O复用------poll

二、poll系统调用 在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者。 <1> poll函数#inlcude <poll.h>int poll(struct pollfd* fds, nfds_t nfds, int timeout);// fds 是一个pollfd结构类型的数组,指定感兴趣的文件描述符上发生的可读、可写和异常// struct pollfd{// in

2016-08-31 22:27:47 287

原创 知识梳理------进程(一)

进程是处于执行状态的程序以及它所包含的资源(可执行的代码、一些用户数据、打开的文件、用于保存临时数据的堆栈、挂起的信号等)的总称。从内核角度看,进程是操作系统分配内存、CPU时间片等资源的基本单位,为正在运行的程序提供运行环境。 <1> 进程描述符(task_struct) 每个进程在内核中都有一个进程描述符来维护其相关信息。该结构定义在/include/linux/sched.h中,大致信息包

2016-08-31 18:56:35 359

原创 知识梳理------信号

信号是由用户、系统或者进程发送给目标进程的信息,以通知目标进程某个状态的改变或系统异常。 <1> 信号的产生方式包括: * 对于前台进程,输入特殊的终端字符来发送信号 * 系统异常(浮点异常、非法内存段访问) * 系统状态变化(alarm定时器到时,产生SIGALRM信号) * 使用kill函数或者kill命令:#inlcude <sys/types.h>#include <signal

2016-08-30 21:32:05 280

原创 I/O复用------select

I/O复用使得程序能同时监听多个文件描述符。其适用场合为:客户端:同时处理多个socket,同时处理用户输入和为网络链接。服务端:同时处理监听、链接socket,同时监听多个端口,同时处理TCP和UDP请求。 注意:I/O复用本身是阻塞的,当多个描述符同时就绪时,如果不使用多进程/多线程,那么就会按顺序依次处理。一、 select系统调用 在一段时间内,监听用户感兴趣的文件描述符上

2016-08-30 10:57:35 314

原创 二叉树------寻找二叉树中两个结点的最近公共祖先

题目描述: 给定一棵二叉树以及它的两个结点,求这两个结点在这棵二叉树中的最近公共祖先结点。 思路分析: 1. 倘若这棵二叉树是一棵二叉查找树,那么就从根结点开始,使用前序遍历每个结点,当到达某个结点n时,若有结点n的值大于其中一个结点而小于另一个结点,则结点n就是要找的结点; 2. 若二叉树中,每个结点都有一个指向其父结点的指针,那么此问题就可以转化为寻找两个链表的第一个公共结点。 3.

2016-08-27 16:43:35 972

原创 二叉树------序列化与反序列化二叉树

题目描述: 实现两个函数,分别用来序列化和反序列化一棵二叉树。 分析:对于序列化:使用前序遍历,递归的将二叉树的值转化为字符,并且在每次二叉树的结点不为空时,在转化val所得的字符之后添加一个’ , ‘作为分割。对于空节点则以 ‘#’ 代替。char* Serialize(TreeNode *root){ if(root == NULL) return NULL;

2016-08-09 12:18:47 434

原创 二叉树------之字形打印二叉树

题目描述: 实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。 分析: 对于一个n层的二叉树,可以使用一个数组将二叉树按层序记录下来,特别的为了明确的分割每一层,要将二叉树的前n-1层填满。方法是,对于一个NULL节点,若在它之后还有不为NULL的结点那么就用NULL填充它的子节点位置,直到遍历完所有位

2016-08-08 18:30:38 805

原创 二叉树------对称二叉树

题目描述: 给定一棵树,判断它是不是对称二叉树。 分析: 面对此题,开始时想使用树的中序遍历,二叉树对称时,其中序遍历结果是一个回文串。但这只是一个必要非充分条件,例如对于二叉树{5, 5, 5, 5, #, #, 5, #, 5} 它的中序遍历结果是一个回文串,但它不是一棵对称二叉树。然后,考虑使用递归,对称二叉树与其镜像完全相同,则递归的判断当前结点与其镜像结点的值是否相同,从而来判断二叉

2016-08-08 17:23:59 409

原创 二叉树------二叉树的下一个结点

题目描述: 给定一棵二叉树和一个结点,要求找到中序遍历此树时该结点的下一个结点。 分析: 中序遍历一棵二叉树时,要根据一个结点有无右子树而分开讨论。若当前结点有右子树,则它的下一个结点就是其右子树的最左叶子结点;若当前结点没有右子树,那么又分两种情况: *若当前结点是其父节点的左孩子结点,那么其下一个结点就是其父结点; *若当前结点是其父节点的有孩子结点,那么沿着指向其父结点的指针向

2016-08-08 16:56:13 389

原创 链表------删除链表中所有重复的结点

题目描述: 给定一个排序链表,要求删除链表中所有的重复结点.(例如: 1->2->2->3->3->4 处理后 1->4) 分析: 使用三个指针front、cur、last,初始时,front = NULL;cur = pHead;last = pHead->next;每一次判断cur->val == last->val . 1. 若相等,则last继续向后移动,直到第一个不等的结点或

2016-08-08 16:33:43 580

原创 链表------带环链表的环入口结点

题目描述: 给定一个带环链表,要求找到其环入口结点. 分析:首先要确定是否有环. 此部分可以使用快慢指针的思想设有指针p和q, 从链表第一个结点开始,p每次移动一步, 而q每次移动两步, 看最终是否会有(p != NULL && q != NULL && p == q) 从而就可判定链表是否有环;若链表有环,则经过第一步之后p和q都指向环中的同一个结点,现在继续使得q沿着链表移动并进行计数

2016-08-08 15:56:12 306

原创 字符串------字符流中第一个不重复的字符

题目描述: 实现一个函数用来找出字符流中第一个只出现一次的字符。 分析: 使用ASCII字符集只有256个字符,可以定义一个长度为256的数组,使得数组下标对应的的记录字符出现的位置,初始时数组的每个元素都初始化为-1. 每遇到一个字符,先判断在数组中的对应位置上的值是否为-1,若是,则表示当前遇到的字符是第一次出现,就将对应位置改为1;若数组的对应位置不是-1,则表示当前遇到的字符已经出现过

2016-08-08 11:17:47 519

原创 字符串------表示数值的字符串

题目描述: 实现一个函数用来判断字符串是否表示数值(包括整数和小数以及使用科学计数法表示的数)。 分析: 表示数值的字符串的规则有:第一个字符只能是’+’ 、’-‘以及数字;数字字符后面只能接’.’或’e’/’E’;小数点后面必须要有字符且只能接数字字符或’e’/’E’;‘e’/’E’后面必须要接字符且只能接数字字符或者’+’ / ‘-‘;‘+’ / ‘-’ 后面必须要接数字字符;

2016-08-08 10:50:50 393

原创 字符串------正则表达式匹配

题目描述: 请实现一个函数用来匹配包括’.’和’‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次)。 分析: 难点主要是一个匹配成功的字符后面紧接着出现’*’应该如何处理. 可以分三种情况: 文本串不移动, 匹配串移动两个字符;文本串移动一个字符, 匹配串不移动;文本串移动一个字符, 匹配串移动两个字符;bool match(char

2016-08-08 10:25:58 277

原创 数组------构建乘积数组

题目描述: 给定数组A[n] = {0, 1, …, n-1},要求构建一个数组B[n],使得B[i] = A[0]A[1]…A[i-1]A[i+1]…A[n-1].并且不能使用除法. 分析: 若能使用除法,则B[i] = A[0]A[1]…A[n-1] / A[i].但由于不能使用除法,所以此方法不可行. 方法一: 可以使用蛮力方法,对每个B[i]都重新乘一遍,从而得到结果,复杂度是O(n

2016-08-08 09:29:11 317

原创 数组------数组中的重复数字

题目描述: 给定一个长度为n的数组,所有的数组都在0到n-1的范围内,请找出数组内的任意一个重复数字。 分析: 1. 将数组排序,然后从头遍历到第一个重复数字为止; 2. 由于数组长度为n且范围是[0, n-1],那么当数组没有重复元素时, 将其排序的结果是对应下标里的数字等于下标,则我们可以从arr[0]开始,若arr[i] == i,则i++, 否则就比较arr[i]和arr[arr[i

2016-08-06 22:27:36 222

原创 数组------将数组元素排成最小数

题目描述: 给定一个数组,将其中的元素组合成一个最小数. 分析: 1. 可以使用蛮力枚举的方法,将所有的可能性都枚举出来,算法复杂度是O(n!) 2. 可以自己制定规则,对于两个数字m 和 n ,将其拼接成数字 mn 或 nm ,判断它们的大小.若mn < nm 那就定义m < n,反之 n < m 或 n = m ; 通过这种方法将数组中所有的数都排序(升序),然后得到结果。(实现时,可

2016-07-29 22:06:58 263

原创 数组------数组中的逆序对

题目描述: 给定一个数组,求该数组中的逆序对的个数. 分析: 1. 最简单的方法是使用暴力枚举法.用双重循环,一一比对数组中的每个元素与排在他后面的所有元素,此方法的时间复杂度是O(n^2).void func(vector<int>& data){ if(data.size() < 1) return 0; int count = 0; for(int

2016-07-29 18:04:24 288

原创 数组------找出数组中只出现一次的两个数

题目描述: 给定一个数组arr,其中除了特定的两个数以外,其他数都出现两次,现写程序找出这两个只出现一次的数。 分析: 根据题目的特殊性,需要使用到异或。因为相同两个数的异或结果为0。由此我们考虑把数组分为两部分,设法让两个只出现一次的数分别在这两个不同的数组中,而其余的数两次都出现在同一个数组中,再将两个数组分别异或,得到的结果就是要求的两个数。 实现步骤: (1) 先将

2016-07-18 15:29:52 351

原创 二叉树------二叉查找树的相关内容

性质 若它的左子树不为空,则左子树上所有的结点值均小于它根结点的值;若它的右子树不为空,则右子树上所有的结点值均大于它根结点的值;它的左、右子树也都是二叉查找树。 二叉查找树的相关操作 1.二叉树的二叉链表结点结构定义typedef struct BiTNode{ int data; struct BiTNode *lchild, *rchild;}BiTNo

2016-07-14 16:06:18 206

原创 二叉树------二叉查找树转化为双向链表

题目描述: 将一棵二叉查找树转换为有序的双向链表。 分析: 由于二叉查找树的的特性,可以使用中续编历得到一个升序序列。基于此,可以改造得到一个升序的双向链表。其具体方步骤是:使用递归的方式先找到最左也子结点,使用一个laset指针记录被操作过得最后一个结点。初始时,last = NULL,在每次递归中使得current->left = last;last->right = current;然后

2016-07-14 15:11:16 223

原创 二叉树------和为定值的全部路径

题目描述: 给定一棵二叉树和一个定值sum,要求得到二叉树中从根节点开始到某个叶节点结束的所有路径使得路径上所有结点值的和与sum相等. 分析: 可以使用先序遍历的方法,递归的遍历整棵树。struct TreeNode{ int val; struct TreeNode* left; struct TreeNode* right; TreeNode(in

2016-06-29 09:56:06 468

原创 字符串处理------最长回文子串

题目描述: 给定一个字符串,求它的最长回文子串的长度.方法一:中心扩展法. 由于回文串中,以某个字符为中心的前缀和后缀一定是相同字符。可以利用此方法枚举中心位置,然后进行扩展,从而找到最长回文子串。#include #include using namepace std;int longestPalindrome(string &str, int len);int beg

2016-06-20 15:37:15 237

原创 数组------最小的k个数

问题描述: 求数组中的最小k个数。 分析: <1>使用选择排序的方法来快速实现(O(n)),具体来说就是借助快速排序的思想,把数组分为比主元v小的部分s1,和比主元v大的部分s2。 1.若k <= |s1|,则第k小的元素在s1,就递归的对s1进行相同的操作。 2.若k = |s1| + 1,那就表示主元就是第k小的元素,那就结束算法,此时数组的前k个元素就是要找的最

2016-06-20 15:32:46 227

原创 二叉树------由前序和中序求后序

题目描述:已知一棵树的前序和中序遍历结果,求其后序结果。 分析: 对于一个二叉树而言,若知道其前序和中序,那么就能唯一确定其后序。方法就是通过每次判断,递归的得到每棵子树。Node* Rebuild(int *pre, int *mid, int length){ if(pre == NULL || mid == NULL || length < 1) retu

2016-06-20 11:11:25 237

原创 链表------两个有序链表的合并

题目描述: 给定两个有序链表,将他们合并为一个新的有序链表。Node* Merge(Node *head1, Node *head2){ if(head1 == NULL) return head2; if(head2 == NULL) return head1; Node *head = NULL; if(head1->data <

2016-06-20 10:11:01 445

原创 字符串------子串匹配

题目描述: 设有文本串S和模式串P,现在要P是否为S的一个子串,若是,则返回P在S中开始的位置,若不是,返回-1. 分析: 一般来说,我们可以使用朴素匹配的方法,逐个匹配。假设文本串长为n,模式串长为m,则朴素匹配的时间复杂度为O((n-m+1)*m). //朴素匹配int Search(char *S, char *P){

2016-06-15 22:11:28 746

原创 二叉树------二叉搜索树的后序遍历序列

题目描述: 给定一个序列,判定其是否为一个二叉搜索树的后序遍历序列。 分析: 二叉搜索树的要求是:左子树中的节点都比根节点小,右子树的节点都比根节点大。则,其后序遍历的结果满足要求:根节点是序列的最后一个元素;从左开始找到第一个比它大的元素就是右子树的开始,且有从此元素到倒数第二个元素都比它大。递归的使用此方法对所有字数进行判断,就可得到最终结果。#include <iostream>usi

2016-05-31 10:20:23 316

原创 二叉树------层序遍历

题目描述: 给定一棵二叉树,要求从上到下按层输出。(每一层按从左到右的顺序) 思路: 按照按层创建二叉树的方法,使用一个队列。先将根节点入队,然后每次从队中取出队首元素,并将其左右子节点入队,持续此过程知道队列为空。(NULL不入队)#include <iostream>#include <deque>#include <stdio.h>using namespace std;#def

2016-05-31 09:52:11 232

原创 栈------包含min函数的栈

题目描述: 实现一个栈数据结构,要求包含min()函数(返回当前栈中的最小元素,复杂度O(1)),同时还要有Push,Pop,Top函数且复杂度都是O(1)。 分析: 要实现min()函数,首先想到可以使用一个指针指向栈中最小元素,但是每当弹栈一次进行一次,最小值就有可能发生变化,倘若当前最小被弹出,那就需要找到次小值,此时使用一个指针的思路是不可行的。于是,可以使用一个辅助栈来记录最小元素,

2016-05-28 17:33:57 252

原创 栈------栈的压入和弹出序列

题目描述: 给定两个序列s1和s2,问是否有可能通过对s1进行入栈出栈操作得到s2?(s1中每个元素都不同)。 思路: 若弹出数字刚好是栈顶元素,则直接弹出。若要弹出的数字不在栈顶,那就继续将源序列压入栈中直到它在栈顶位置。若源序列都被压入了栈中,但仍为得到要弹出的数字,则证明s2不可能是s1的一个弹出序列。#include <iostream>#include <stack>using

2016-05-28 16:38:19 372

原创 二叉树------树的子结构

题目描述: 给定两棵二叉树tree1与tree2,现在要求判断tree2是否为tree1的一个子树. 分析: 可以使用递归的方法,找到与tree2根节点值相同的tree1的节点n,然后递归调用函数对以n为根节点的子树进行判定。#include <iostream>#include <stdio.h>using namespace std;#define N 100struct Node

2016-05-26 16:50:00 317

原创 字符串------打印1到最大的n位数

题目描述: 输入位数n,要求打印出从1到最大的n位数。举例来说,若输入3,则打印1到 999 . 思路: 首先,不能简单的使用int 或者 long 等类型来完成此题,因为要考虑大数问题,所以需要使用字符串来模拟。方法是使用一个长为 n+1 的数组number[n+1]来实现,初始时把前n位的值置为 ‘0’ ,最后一位为 ‘\0’ ,然后每次取出第 n-1 位的字符(从0开始),将其转换为整数

2016-05-21 15:01:52 278

原创 位运算------二进制中1的个数

题目描述: 给定一个十进制数n,求它的二进制表示是有几个1. 方法: 可以每次将 n 和 n -1 进行 & 运算并将结果赋予 n,并记录运算次数。直到 n = 0 为止。include <iostream>using namespace std;int numOfOne(int n);int main(){ int array[3] = {258, 369, 147}; f

2016-05-20 11:41:15 352

原创 数组------荷兰国旗问题(颜色排序)

问题描述: 现在有红、白、蓝三色小球若干个,要求对其进行整理,使得同色小球相邻。 思路: 参照快速排序的过程,但使用三个指针first, current 和 end.其中first和current从数组头开始,end指向数组尾。以0表示红色,1表示白色,2表示蓝色。则有: (1) 当*current = 0 时,swap(*current, *first) 并且first++、current

2016-05-17 14:22:14 430

Linux内核设计与实现_第三版_高清

Linux内核设计与实现_第三版_高清.

2015-10-13

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除