自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(118)
  • 收藏
  • 关注

原创 单链表的面试题

void DeleteNotTail(PNode pos);//删除一个无头单链表的非尾节点void InsertNotHead(PNode pHead, PNode pos, DataType data);//在无头单链表的一个非头节点前插入一个节点void JosephCircle(PNode* pHead, int M);//约瑟夫环PNode FindMidNode(PNode pH...

2018-05-10 00:01:12 198

原创 已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={

void difference(PNode* LA, PNode LB){ PNode pa = *LA; PNode pre = NULL; PNode pb = LB; PNode p = NULL; while (pa) { pb = LB; while (pb&&pa->data !=...

2018-05-09 23:57:54 288

原创 双向通信管道

我们知道管道有匿名管道和命名管道,但是他们只能用于单向的通信,现在有一种双向管道用来进行双方的通信:sockpair来实现#include <stdio.h>#include <sys/socket.h>#include <string.h>int main(){ int fd[2]; int ret=socketpair(PF_LOCAL,SOCK_STREAM,0,fd);

2017-08-25 14:54:12 1685

原创 socket编程(TCP多线程客户端服务器)

能够实现一个服务器与多个客户端之间通信 Makefile中引入了pthread库 Makefile.PHONY:allall:server clientserver:server.c gcc -o $@ $^ -lpthreadclient:client.c gcc -o $@ $^ -lpthread.PHONY:cleanclean: rm -f serve

2017-08-24 17:25:08 857 1

原创 socket编程(TCP多进程客户与服务器)

能够实现一个服务器与多个客户端之间通信 server.c#include <stdio.h>#include <string.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/socket.h>#include <stdlib.h>void Usage(char* proc){ printf("usage:

2017-08-24 17:21:57 913

原创 进程间通信之共享内存

共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进

2017-08-15 07:53:10 315

原创 进程间通信之信号量

信号量的本质是一种数据操控锁,它本身不具有数据交换的功能,而是通过来控制其他的通信资源来实现进程间通信的,信号主要负责数据的同步与互斥功能。进程请求一个使用信号量来表示的资源时,首先要读取信号量的值来判断资源是否能被使用,若信号量的值大于0,资源可用,等于0,无资源可用,同时进程会进入睡眠状态,直到有资源可用。当进程不再使用一个信号量控制的共享资源时,信号量的值+1,对信号量的值进行的增减操作均为原

2017-08-14 20:37:00 234

原创 进程间通信之消息队列

消息队列提供了一种从一个进程向另一个进程发送数据块的方法,每个数据块都被认为是由一个类型的,接收者进程接收的数据块可以有不同的类型。消息队列是基于消息的,管道式基于字节流的,可以用发送消息的方式来避免管道的同步与阻塞问题,消息队列的读取,不一定是先进先出。 消息队列与命名管道有一样的不足,就是每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限(MSGMNB),系统上消息

2017-08-14 18:02:48 241

原创 进程间通信之命名管道

前面所说的pipe我们叫它匿名管道,他只能用于有关系的进程之间的通信,为了实现不同进程之间的通信,有一种管道叫做命名管道Fifo来实现任意两个进程之间的通信。命名管道是一个设备文件,总是按照先进先出的工作方式来进行的,在文件系统中是以文件名的形式存在的。 首先创建命名管道可以有2种方式: 1.在shell下用命令mknod或者mkfifo来创建 2.调用系统函数mknod或者mkfifo函数创

2017-08-14 16:13:17 280

原创 进程间通信之匿名管道

我们知道每个进程都有各自 的进程地址空间,一个进程看不到另外一个进程的全局变量,那么要实现进程之间的数据交换,必须要通过内核,首先内核要先开辟缓冲区,进程1先把数据拷贝到内核的缓冲区中,进程2再从缓冲区中把数据拿走,内核提供的这种机制就叫做进程间通信。 管道是一种基本的IPC机制,用于创建管道的函数为pipe;#include <unistd.h>int pipe(int filedes[2])

2017-08-14 15:47:05 467

原创 UDP套接字编程

UDP是用户数据报协议,与TCP协议一样,在网络中处理数据包,是一种无连接的传输层协议,具有不可靠性,UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。 基于UDP的客户端服务器: 服务器:#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#inc

2017-08-10 14:13:40 226

原创 socket编程(TCP单进程客户服务器通信)

服务器#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include <arpa/inet.h>void Usage(char* proc){printf("usage:%s [loc

2017-08-08 12:50:59 370

原创 socket套接字编程预备知识

我们知道“IP+端口号”标识网络通讯中的一个唯一的进程,这里我们说”IP+端口号“就是socket. 介绍一下网络字节序的知识,我们都知道内存中的多字节数据相对于内存地址来说有大端和小端之分,磁盘文件中的多字节数据相对于文件偏移来说也有大端和小端之分,同样网络数据流也有大端和小端之分,发送主机把发送缓冲区中的数据按照内存地址从低到高的顺序发送出去,接收主机把接收到的数据按照内存地址从低到高的顺序保

2017-08-08 10:13:42 234

原创 求二叉树中两个节点的最近公共祖先

要求考虑以下三种种情况,给出解决方案,并解决: 1:二叉树是搜索二叉树。2: 二叉树每个节点有parent(三叉链) 3:就是普通二叉树。(尽可能实现时间复杂度为O(N)) 针对第一种情况,是一棵二叉搜索树,我们可以根据数据的大小来判断两个节点的位置,如果在根节点的2侧,则根节点为最近公共祖先,如果在根节点的同侧,继续寻找2个节点的位置TreeNode* PublicLowParent(TreeN

2017-08-02 22:25:41 833

原创 判断一棵树是否是完全二叉树

首先我们要了解什么事完全二叉树。 完全二叉树: 假设一颗二叉树的深度为h,除了第h层以外,其余各层节点的个数全都达到了每层的最大值,即2^(n-1),只有第h层的结点个数小于或者等于2^(h-1),而且节点都连续集中在最左边,这就是完全二叉树,当然当第h层结点达到最大值时,叫做满二叉树,满二叉树是一种特殊的完全二叉树; 如图所示为完全二叉树: 从根结点开始遍历整棵二叉树,(所假设的节点之前为

2017-08-02 10:55:04 4252 2

原创 判断一个节点是否在一棵二叉树中&&判断一颗二叉树是是否是另一颗树的子树

1.判断一个节点是否在一颗二叉树中 首先判断此节点是不是根节点,是根节点的话就返回表示节点在树中,否则递归根节点的左右子树,继续向下寻找bool _IsNode(Node* node,Node* root) { if (root == NULL) return false; //节点位根节点 if (node->_da

2017-08-02 09:50:42 596

原创 已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={

void difference(PNode* LA, PNode LB){ PNode pa = *LA; PNode pre = NULL; PNode pb = LB; PNode p = NULL; while (pa) { pb = LB; while (pb&&pa->data != pb->data)//数据

2017-08-02 09:45:09 335

原创 一个数组中有一个数字的次数超过了数组的一半,求出这个字符

首先我们想到的就是排序,排序完成后找到中间的数字即为数组中超过一半的数字,但是后来又想想,数据特别多的话排序就显得力不从心。 本题可以用标志位来标记数据:首先记录一个数据,继续遍历下一个数据,如果数据以第一个相同,就将标志位加一,继续下一个数据,要是不相同就将标志位减一,如果标志位为0.重新记录数据int findhalf(int *a, int sz){ int flag = 0;

2017-08-02 09:38:21 249

原创 给定一个整数N,那么N的阶乘N!末尾有多少个零呢?

我们知道最小的两个数相乘能出来0的就是2和5了,那么对于所有整数来说,能被2整除的数要多于能被5整除的数,所以这道题的解题思路就是:判断从1-N这些数中一共有包含的5的个数。 代码如下:int NumZero(int n){ int count = 0; for (int i = 1; i <= n; i++)//找寻1-n中每个数字包含的5个个数的总和 {

2017-08-02 09:11:00 1215

原创 一个m*n的矩阵,从左到右从上到下都是递增的,给一个数x,判断x是否在矩阵中。要求效率尽可能的高

我们可以这样入手,比如给一个3*3的二维数组,从每一行的最大值开始比较: 1.如果X大于a[0][2],第一行中的数据肯定都比x小,所以继续跟下一行的a[1][2]比较 2.如果X小于a[0][2],第3列中的数据肯定都比x大,所以继续跟上一列的 a[0][1]比较 3.循环条件为行数>=0;列数<=n-1; 实现代码如下:#define M 3#define N 3bool Find

2017-08-02 09:03:34 835

原创 求一颗二叉树的镜像

下面我给出一棵二叉树和他的镜像,所谓镜像就是一棵树就跟在镜子中显示一样,左右反转,示意图如下: 根节点的左右孩子互换,我们可递归实现:void _MirrorTree(Node* root) { if (root == NULL)//树为空 return; if (root->_left == NULL&&root->_right

2017-08-02 08:51:36 265

原创 c语言模拟实现c++的继承多态

c++有封装、继承和多态三大特性,其中多态分为静态多态与动态多态,动态多态是通过虚函数实现的,一个类中如果有虚函数,那么就需要维护一张虚表来存放虚函数的地址,c语言中我们用结构体来模拟类。 代码如下: 其中A模拟父类,B模拟子类#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <stdlib.h>void funA()

2017-08-01 11:05:06 224

原创 BloomFilter布隆过滤器

1、简介: BloomFilter是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。 2、应用: 要判断一个元素是否在一个集合中出现,一般情况下就是将这个集合的元素保存下来,然后再到这个集合中一一比较即可,但是如果这个集合中的元素很多的话,不仅需要的内存很大,而且查找起

2017-05-31 12:41:25 329

原创 并查集解决朋友圈问题

首先我们来看一道题笔试题,关于朋友圈的问题: 解决这个问题,我们可以用并查集来解决。 并查集是一种数据结构,用于处理不相交集合中的合并以及查询问题,将N个元素分成一组不相交的集合,开始时我们把每一个元素当成一个集合,然后按规律将集合合并。举例说明,首先定义一个只有10个元素的数组,并将每个元素的值设置为-1假设每个元素在集合中的关系如下: 看上图中的第一个树,0,6,7,8在用一个集合

2017-05-31 10:52:06 1344

原创 位图

位图法就是bitmap的缩写。所谓bitmap,就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在的。在STL中有一个bitset容器,其实就是位图法。 举个例子来说明一下: 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。 40亿个数全部存放大约要用16G的内存空间,这肯定是不现实

2017-05-09 21:43:22 409

原创 大数据处理问题

首先让我们明确一下内存之间的换算:1> 1Byte=8bit2>1KB=1024Byte=1024*8 bit3>1MB=1024KB=1024*1024Byte=1024*1024*8bit4>1G=1024MB=1024*1024KB=1024*1024*1024Byte(大约一亿个字节)=1024*1024*1024*8bit1)给一个超过100G大小的log f

2017-04-29 14:35:35 559

原创 stat对文件的操作的三个时间

Linux中的stat是用来显示文件信息的,首先让我们来看一下他都显示了什么信息。 建立一个test.c文件,用stat来查按文件的一些信息: 其中,我们看到了一些有关事件的东西,其中包括3种时间信息 1>Access:文件最后一次被访问的时间 2>Modify:文件最后一次被修改的时间 3>Change:文件的属性最后一次被修改的时间,比如文件的权限,大小等属性 touch -a

2017-04-20 21:22:12 580

原创 哈夫曼树应用——文件压缩

1.哈夫曼树的简介: 哈夫曼树(Huffman tree),又名最优树,指给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。 2.哈夫曼树的构造方式如下: 比如说有一组数,1,4,3

2017-04-16 22:57:39 4278 3

原创 atexit函数解析

进程终止的方式有8种,如下所列出,其中前5种是正常的终止,后三种是异常的终止: 1.从main函数返回 2.调用exit函数 3.调用_exit函数或者_EXIT函数 4.最后一个线程从启动历程返回 5.最后一个线程调用pthread_exit 6.调用abort函数 7.接到一个信号并终止 8.最后一个线程对取消请求做出响应 exit()和_exit()以及_Exit()函数的

2017-04-16 13:46:15 324

原创 平衡二叉搜索树——红黑树

1.红黑树的简介 红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位_color来表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子简单 路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似于平衡。红黑树没有达到AVL树的高度平衡,换句话说,它的高度,并没有AVL树那么高的要求,但他的应用却更加的广泛,实践中是相当高效的,他可以在O(log2 n)的时间内做查

2017-04-12 16:07:57 288

原创 平衡二叉搜索树——AVL树

1.AVL树的定义 AVL树又称为高度平衡的二叉搜索树,是1962年有俄罗斯的数学家G.M.Adel’son-Vel’skii和E.M.Landis提出来的。它能保持二叉树的高度 平衡,尽量降低二叉树的高度,减少树的平均搜索长度。 2.AVL树的性质 (1) 左子树和右子树的高度之差的绝对值不超过1 (2)树中的每个左子树和右子树都是AVL树 (3)每个节点都有一个平衡因子(balanc

2017-04-12 11:42:08 381

原创 二叉搜索树

二叉搜索树满足以下性质: 1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。 2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。 3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。 4. 左右子树都是二叉搜索树。二叉搜索树可以进行插入、查找、删除等操作,现在以非递归方法实现下列操作:#pragma once#inclu

2017-04-12 10:31:22 182

原创 树&&二叉树

1.树的基本概念 树是一种非线性的数据结构,是由n(n>=0)个有限个数据的元素集合,形状像一颗倒过来的树。就像是这样: 树是由唯一的根和若干互不相交的子树组成的。其中的每一颗子树又是一棵树,也是由唯一根节点和互不相交的子树构成。因此,树的定义是递归的。值得注意的是,当一颗树没有节点时,称这棵树为空树。 2.关于树的一些相关术语 (1)节点:结点包含数据和指向其它节点的指针。 (2)根节点

2017-04-12 10:04:42 275

原创 map应用-统计K个最喜欢的水果

一共写出了3种方案,都是用map实现的,方案三利用了[]的重载机制,统计出每个水果出现的次数之后,建堆,进行排序#include <iostream>#include <map>#include <vector>#include <algorithm>#include <string>using namespace std;//统计水果出现的次数struct Max{ boo

2017-04-11 16:35:41 304

原创 map,multimap,set,multiset

map和set我们之前介绍过了,现在通过对比说明一下map与multimap,set与multiset首先map的插入操作,不能插入已经存在的键值,若插入已经存在的键值,则插入无效,可应通过相应的办法来解决:void TestMap(){ map<string, string> dict; //[]能修改已存在键值的实值 dict["left"] = "左边"; d

2017-04-11 12:56:35 283

原创 堆的介绍与应用

堆是一种特殊的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。 堆结构的二叉存储分为2种形式,分别是最大堆和最小堆,最大堆就是每个父节点的值都大于或等于孩子节点的值,最小堆刚好与之相反,每个父节点的值都小于或等于孩子节点的值。 用以下代码实现一个堆,默认情况下是大堆的形式:#include <iostream>

2017-04-10 21:20:30 356

原创 简单进度条的实现

首先让我们先来看进度条实现的代码:#include <stdio.h>#include <unistd.h>#include <string.h>int main(){ char bar[102]; memset(bar,0,102*sizeof(char)); char s[]="|/-\\"; bar[0]='\0'; int i=0; while(i<=100)

2017-04-08 17:07:04 482

原创 STL中的set&&map

首先看一下set与map的介绍:set关联式容器,set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Re

2017-02-16 15:12:56 246

原创 <STL>模拟实现Vector

首先,这里用到了类型萃取的知识,代码如下:struct __TrueType{ bool Get() { return true; }};struct __FalseType{ bool Get() { return false; }};template <class _Tp>struct TypeTrai

2016-12-10 15:12:34 308

原创 <STL>模拟实现List

STL可分为容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adaptors)、算法(algorithms)、仿函数(functors)六个部分。 1.库中list的使用方法#include <iostream>#include <list>#include <algorithm>#include <stdlib.h>using nam

2016-12-10 09:25:53 309

空空如也

空空如也

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

TA关注的人

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