自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(76)
  • 资源 (18)
  • 问答 (2)
  • 收藏
  • 关注

原创 POSIX线程

在前面,我们介绍了如何在Linux (包括UNIX)中处理讲程。类UNIX操作系统早就具备这种多进程功能了。但有时人们认为,用fork调用来创建新进程的代价太高。在这种情况下,如果能让一个进程同时做两件事情或至少看起来是这样将会非常有用。而且,你可能希望能有两件或更多的事情以一种非常紧密的方式同时发生。这就是需要线程发挥作用的时候了。什么是线程**在一个程序中的多个执行路线就叫做线程(thread)。更准确的定义是:线程是一个进程内部的一个控制序列。**虽然Linux和许多其他的操作系统一样,都擅长同时

2021-11-21 11:17:36 1382

原创 文件锁定.

文件锁定是多用户、多任务操作系统中一个非常重要的组成部分。程序经常需要共享数据,而这通常是通过文件来实现的。因此,对于这些程序来说,建立某种控制文件的方式就非常重要了。只有这样,文件才可以通过一种安全的方式更新,或者说,当一个程序正在对文件进行写操作时,文件就会进入一个暂时状态,在这个状态下,如果另外一个程序尝试读这个文件,它就会自动停下来等待这个状态的结束。Linux提供了多种特性来实现文件锁定。其中最简单的方法就是以原子操作的方式创建锁文件,所谓“原子操作”就是在创建锁文件时,系统将不允许任何其他的事

2021-11-19 23:53:11 987

原创 Liunx环境相关函数

为Linux(或UNIX和类UNIX系统)编写程序时,你必须考虑到程序将在一个多任务环境中运行。这意味着在同一时间会有多个程序运行,它们共享内存、磁盘空间和CPU周期等机器资源。甚至同一程序也会有多个实例同时运行。最重要的是,这些程序能够互不干扰,能够了解它们的环境,并且能正确运行,不产生冲突(例如,试图与其他程序同时写同一个文件)。在本篇中,我们将介绍程序运行的环境,程序如何通过环境来获得有关其运行条件的信息,以及用户怎样改变程序的行为。程序参数当一个用C语言编写的Linux或UNIX程序运行时,它

2021-11-18 12:17:58 1150

原创 文件维护及扫描目录

文件和目录的维护标准库和系统调用为文件和目录的创建与维护提供了全面的支持。chmod系统调用你可以通过chmod系统调用来改变文件或目录的访问权限。这构成了shell程序chmod的基础。该函数原型如下:#include <sys/stat.h>int chmod(const char *path,mode_t mode);path参数指定的文件被修改为具有mode参数给出的访问权限。参数mode的定义与open系统调用中的一样,也是对所要求的访问权限进行按位OR操作。除非程序被

2021-11-16 23:16:58 813

原创 底层文件访问

底层文件访问每个运行中的程序被称为进程( process),它有一些与之关联的文件描述符。这是一些小值整数,你可以通过它们访问打开的文件或设备。有多少文件描述符可用取决于系统的配置情况。当一个程序开始运行时,它一般会有3个已经打开的文件描述符:0:标准输入1:标准输出2:标准错误你可以通过系统调用open把其他文件描述符与文件和设备相关联,稍后讲解。其实使用自动打开的文件描述符就已经可以通过write系统调用来创建一些简单的程序了。write系统调用系统调用write的作用是把缓冲区buf

2021-11-15 16:08:21 1389

原创 进程间通信:信号量

进程间通信的机制,它们最初由AT&T System V.2版本的UNIX引IPC (Inter-Process Communication,进程间通信)机制,或被更常见的称为System V IPC。正如我们所看到的,它们并不是进程间通信的唯一方法,但人们通常把这些特定的机制称为System V IPC。信号量当我们编写的程序使用了线程时,不管它是运行在多用户系统上、多进程系统上,还是运行在多用户多进程系统上,我们通常会发现,程序中存在着一部分临界代码,我们需要确保只有一个进程(或一个执行线程)

2021-11-13 22:17:49 1619

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

我们现在来学习第三个也是最后一个System V IPC机制:消息队列(message queue)。消息队列与命名管道有许多相似之处,但少了在打开和关闭管道方面的复杂性。但使用消息队列并未解决我们在使用命名管道时遇到的一些问题,比如管道满时的阻塞问题。消息队列提供了一种在两个不相关的进程之间传递数据的相当简单且有效的方法。与命名管道相比,消息队列的优势在于,它独立于发送和接收进程而存在,这消除了在同步命名管道的打开和关闭时可能产生的一些困难。消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法

2021-11-11 22:25:22 807

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

共享内存是3个IPC机制中的第二个。它允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间传递数据的一种非常有效的方式。虽然X/Open标准并没有对它做出要求,但大多数共享内存的具体实现,都把由不同进程之间共享的内存安排为同一段物理内存。共享内存是由IPC为进程创建的一个特殊的地址范围,它将出现在该进程的地址空间中。其他进程可以将同一段共享内存连接到它们自己的地址空间中。所有进程都可以访问共享内存中的地址,就好像它们是由malloc分配的一样。如果某个进程向共享内存写入了数据,所做的

2021-11-11 12:29:58 1461

原创 make命令和makefile文件

多个源文件带来的问题在编写小程序时,许多人都会在编辑完源文件后重新编译所有文件来重建应用程序。但对大型程序来说,使用这种简单的处理方式会带来一些很明显的问题。编辑一编译—测试这一循环的周期将变长。如果仅改动了一个源文件,即使是最有耐心的程序员也不想重新编译所有的源文件。如果在程序中创建了多个头文件,并在不同的源文件中包含它们,这种处理方式就会带来一个潜在的、更严重的问题。比如说,你有3个头文件: a.h、b.h和c.h,3个C源文件main.c、2.c和3.c(我们希望读者在实际的项目中为源文件选择更好

2021-11-10 23:15:44 1609

原创 进程间通信:管道

什么是管道当从一个进程连接数据流到另一个进程时,我们使用术语管道(pipe)。我们通常是把一个进程的输出通过管道连接到另一个进程的输入。大多数Linux的用户应该早已对将shell命令连接在一起的概念很熟悉了,这实际上就是把一个进程的输出直接传递给另一个进程的输入。对于shell命令来说,命令的连接是通过管道链接的,如下所示cmd1 | cmd2shell负责安排两个命令的标准输入和标准输出。cmd1的标准输入来自终端键盘。cmd1的标准输出传递给cmd2,作为它的标准输入。cmd2的标准输出连

2021-11-10 23:09:55 2010

原创 进程间通信:信号

信号信号是UNIX和Linux系统响应某些条件而产生的一个事件。接收到该信号的进程会相应地采取一些行动。我们用术语生成(raise)表示一个信号的产生,使用术语捕获(catch)表示接收到一个信号。信号是由于某些错误条件而生成的,如内存段冲突、浮点处理器错误或非法指令等。它们由shell和终端处理器生成来引起中断,它们还可以作为在进程间传递消息或修改行为的一种方式,明确地由一个进程发送给另一个进程。无论何种情况,它们的编程接口都是相同的。信号可以被生成、捕获、响应或(至少对于一些信号)忽略。信号的名称

2021-11-10 09:36:08 1135

原创 启动新进程

system函数我们可以在一个程序的内部启动另一个程序,从而创建一个新进程。这个工作可以通过库函数system来完成。include <stdlib.h>int system (const char *string) ;system函数的作用是,运行以字符串参数的形式传递给它的命令并等待该命令的完成。命令的执行情况就如同在shell中执行如下的命令:sh string如果无法启动shell来运行这个命令,system函数将返回错误代码127;如果是其他错误,则返回-1。否则,s

2021-11-09 15:02:48 857

原创 进程的结构

什么是进程UNIX标准(特别是IEEE Std 1003.1,2004年版)把进程定义为:一个其中运行着一个或多个线程的地址空间和这些线程所需要的系统资源。 目前,可以把进程看作正在运行的程序。像Linux这样的多任务操作系统可以同时运行多个程序。每个运行着的程序实例就构成一个进程。作为多用户系统,Linux允许许多用户同时访问系统。每个用户可以同时运行许多个程序,甚至同时运行同一个程序的许多个实例。系统本身也运行着一些管理系统资源和控制用户访问的程序。正在运行的程序或进程由程序代码、数据、变量(占

2021-11-09 13:26:56 2466

原创 Liunx上的C程序与库文件编译调试

编译链接预编译阶段a) 删除所有的“#define”,并且展开所有的宏定义;b) 处理所有的条件预编译指令,“#if”、“#ifdef”、“#endif”等;c) 处理“#include”预编译指令,将被包含的文件插入到该预编译指令的位置;d) 删除所有的注释;e) 添加行号和文件名标识,以便于编译器产生调试用的符号信息及编译时产生编译错误和警告时显示行号;f) 保留所有的#pragma 编译器指令,因为编译器需要使用它们。编译阶段词法分析、语法分析、语义分析,代码优化,汇总符号。汇

2021-11-08 22:42:26 117

原创 死锁应对.

发生死锁的原因大部分人可能都见过交通阻塞,一大堆汽车因为争夺行路权,互不相让而造成阻塞。又或者因车辆发生故隙抛锚或两辆车相撞,造成道路阻塞。在这种情况下,所有的车都停下来,谁也无法前行,这就是死锁。死锁的发生,归根结底是因为对资源的竞争。 因为大家都想要某种资露,但又不能随心所欲地得到所有资源,在争夺的僵局中,导致任何人都无法继续推进。在一个多道编程的环境里,一个系统里存在多个进程或线程,面这些远程和线程共享该计算机系统里的资源。因为资源竞争面造成系统无法继续推进就是难以避免的了。这里所说的资源就是一

2021-11-08 22:05:38 283

原创 Linux常用命令

Ubuntu内部命令和外部命令内部命令和外部命令功能基本相同,但也有些细微差别。使用type "cmd"可以分辨内部命令内部命令实际上是shell程序的一部分,其中包含的是一些比较简单的linux系统命令,这些命令由shell程序识别并在shell程序内部完成运行,通常在linux系统加载运行时shell就被加载并驻留在系统内存中。内部命令是写在bash源码里面的,其执行速度比外部命令快,因为解析内部命令shell不需要创建子进程。比如:exit,history,cd,echo等。外部命令

2021-11-08 15:51:41 278

原创 Linux文件

文件文件类型Linux 下所有的东西都可以看做文件,Linux 将文件分为以下几种类型:普通文件 ‘-’目录文件 ‘d’管道文件 ‘p’链接文件 ‘l’设备文件(块设备 ’b’ 、字符设备 ‘c’)套接字文件 ‘s’Linux 上不以文件的扩展名区别文件类型,而是在文件属性中有一列专门记录文件类型。权限r 读权限 值: 4w 写权限 值: 2x 执行权限 值: 1无权限 值: 0u : 表示文件属主的访问权限g : 表示文件同组用户的访问权限o : 表示其他用户的

2021-11-08 12:42:10 132

原创 输入输出.

什么是输入输出计算机归根结底是为人类服务的,这就要求计算机必须提供某种机制使得人可以向计算机发出命令或操纵计算机。也就说计算机与人之间必须存在某种沟通的机制。 这种沟通的机制就是计算机的输入输出机制。输入提供的是一个“人→计算机”的通道。即人或外部世界通过输人向计算机发出命令或提供数据。输出提供的则是相反方向的通道,即“计算机→人”的通道。计算机通过这个通道向人或外部世界输出自己的计算结果,包括对其他设备的控制操纵命令。显然,输入输出的存在才使得计算机的存在有了意义。就像一个人,如果没有输入输出,即他

2021-11-07 23:21:23 1864

原创 优先级倒挂(priority inversion)

优先级倒挂( priority inversion)在之前已经有所提及。其所指的是一个低优先级任务持有一个被高优先级认为所需要的共享资源。这样高优先级任务因资源缺乏处于受阻状态,一直到低优先级任务释放资源为止。 这样实际上造成了这两个任务的优先级倒挂。如果此时有其他优先级介于二者之间的任务,并且其不需要这个共享资源,则该中级优先级的进程将获得CPU控制,从面超越这两个任务。在某些时候,优先级倒挂并不会造成损害。高优先级任务的延迟并不会被注意,因为低优先级进程最终会释放资源。但在其他一些时候,优先级倒挂则可

2021-11-05 19:55:57 755

原创 进程调度.

调度的目标前面讲过,在多进程,多线程并发的环境里,虽然从概念上看,有多个进程或线程在同时执行,但在单一CPU下,实际上在任何时刻只能有一个进程或线程处于执行状态。而其他线程则处于非执行状态。那么这就有一个需要解决的问题:我们是如何确定在任意时刻到底有哪个线程执行,哪些不执行呢?或者说,我们是如何进行线程调度的呢?进程/线程的调度是操作系统进程管理的一个重要组成部分。其任务是怎么选择下一个要运转的进程。而要探明这一点,则首先需要确定操作系统进程调度的目标是什么。这样,就知道选择什么进程最合适。那么操作系

2021-11-04 23:01:21 615

原创 散列(Hash)

散列表的实现常称为散列(hashing)。散列是一种用于以常数平均时间执行插入、删除和查找的技术。但是,那些需要元素间任何排序信息的操作将不会得到有效的支持。因此,诸如findMin、findMax以及在线性时间内按顺序打印整个表的操作都是散列表所不支持的。基本概念理想的散列表数据结构只不过是一个包含一些项的具有固定大小的数组。查找一般是对项的某个部分(即数据成员)进行,这部分称为键(key)。例如,项可以由字符串(它可以作为键)和附加的数据成员组成。我们把表的大小记作TableSize,并将其理解为

2021-11-04 12:35:26 2434

原创 进程同步.

为什么要同步我们前面说过,线程之间的关系是合作关系。既然是合作,那就得有某种约定的规则,不然合作就会出问题。例如,假如我们有两个线程同时运行,第一个线程在执行了一些操作后想检查当前的错误状态errno,但在其作出检查之前,线程2却修改了errno。这样,当第一个线程再次获得控制权后,检查将是线程2改写过的errno,这是不正确的,如图所示。之所以出现上述问题,是因为两个原因:errno是线程之间共享的全局变量。线程之间的相对执行顺序是不确定的。因此,要解决上述问题有两个办法,即分别消除上述两

2021-11-04 09:42:37 397

原创 线程通信(ITC)

为什么要通信通信是人的基本需求。而进程作为人的发明,自然脱离不了人的习性,也有通信需求。如果进程之间不进行任何通信,那么进程所能完成的任务就要大打折扣。 例如,父进程在创建子进程后,通常须要监督子进程的状态,以便在子进程没有完成给定的任务时,可以再创建一个子进程来继续。这就需要父子进程间通信。而线程间的通信则需要更多。由于一个进程通常包括多个线程,这多个线程之间因资源共享自然地就存在一种合作关系。这种合作关系虽然可以表现为相互独立,但更多地时候是互相交互。这就是通信。就像舞台上的多个演员,他们之间是一种

2021-11-02 22:53:17 5996

原创 线程(Thread)

线程概念那么线程是什么?我们知道,进程是运转的程序,是为了在CPU上实现多道编程而发明的一个概念。但是进程在一个时间只能干一件事情。 如果想同时干两件事,例如同时看两场电影,我们自然想到传说中的分身术,就像孙悟空那样同时变出多个真身。当然,人在现实中进行分身是办不到的。但进程却可以办到,办法就是线程。线程就是我们为了让一个进程能够同时干多件事情而发明的“分身术”。既然线程是进程的分身,每个线程自然在本质上是一样的,即拥有同样的程序文本。但由于是分身,自然也应该有不一样的地方,这就是线程执行时的上下文不

2021-11-02 21:21:39 7651

原创 进程(Process)

进程概念进程管理.内存管理和文件管理是操作系统的三大核心功能。那么什么是进程呢?顾名思义,进程就是进展中的程序,或者说进程是执行中的程序。 就是说,一个程序加载到内存后就变为进程。即:进程=程序+执行单一操作员单一控制终端、批处理均存在效率低下的问题,即CPU使用率不高。为了提高CPU利用率,人们想起将多个程序同时加载到计算机里,并发执行。这些同时存在于计算机内存的程序就称为进程。进程让每个用户感觉到自己独占CPU。因此,进程就是为了在CPU上实现多道编程而出现的概念,如图所示。进程模型那么进程到

2021-11-02 19:53:33 4150

原创 树.(三)

本篇主要介绍一下常用的树结构二叉树每个结点至多拥有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。二叉树的性质1.若二叉树的层次从0开始,则在二叉树的第i层至多有2i个结点(i>=0)2.高度为k的二叉树最多有2(k+1) - 1个结点(k>=-1)(空树的高度为-1)3.对任何一棵二叉树,如果其叶子结点(度为0)数为m,度为2的结点数为n ,则m - n + 1满二叉树除叶子节点外,所有节点都有左右两孩子完全二叉树如果对满二叉树

2021-11-02 14:56:16 65

原创 树.(二)

线索二叉树线索二叉树原理我们现在提倡节约型社会,一切都应该节约为本。对待我们的程序当然也不例外,能不浪费的时间或空间,都应该考虑节省。我们先来观察一颗二叉树,会发现指针域并不是都充分的利用了,有许许多多的“^”,也就是空指针域的存在,这实在不是好现象,应该要想办法利用起来。在二叉链表上,我们只能知道每个结点指向其左右孩子结点的地址,而不知道某个结点的前驱是谁,后继是谁。要想知道,必须遍历一次。以后每次需要知道时,都必须先遍历一次。为什么不考虑在创建时就记住这些前驱和后继呢,那将是多大的时间上的节省。

2021-11-02 13:43:43 183

原创 操作系统基本概念

计算机硬件基本知识从概念上讲,计算机的结构非常简单:首先布置一根总线,然后将各种硬件设备挂在总线上。所有这些设备都有一个控制设备,外部设备都由这些控制器与CPU通信。所有设备之间的涌信均需通过总线、如图所示。图中的粗线条为总线。为了提高计算机的效率,人们又设计出了流水线结构,即仿照工业流水装配线,将计算机的功能部件分为多个梯级,并将计算机的每条指令分拆为同样多个步骤,使每条指令在流水线上流动,到流水线最后一个梯级时指令执行完毕。流水线上的每个梯级都可以容纳一条指令同时执行,如上图所示。为了进一步提高

2021-11-01 22:34:10 419

原创 操作系统历史

第一阶段:状态机操作系统(1940年以前)这是计算机处在萌芽期时出现的操作系统。这种操作系统运行在英国人巴贝斯 ( Babbes )想像中的自动机中。 所谓状态机操作系统实际上算不上是我们现在通常所定义的操作系统,而是一种简单的状态转换程序:根据特定输入和现在的特定状态进行状态转换而已。这个时候的计算机也不是现代意义上的计算机,而是所谓的自动机,其功能非常简单,可以用“原始”来形容。能做的计算也只限于加减法。这个时代的操作系统没有什么功能,不支持交互命令输入,也不支持自动程序设计。甚至这个时候还没有存储程

2021-11-01 21:15:23 1716

原创 操作系统导论

程序是如何运行的计算机程序是怎样运行的呢?对于多数人来说,或多或少地知道任何程序必须首先有人写出来,即“编程”,然后放到计算机里即可运行。这种解释当然是过于简单了。计算机程序的运行实际上是一件十分复杂的事情,牵扯到方方面面。首先当然是进行编程,而编程需要计算机程序设计语言作为基础。对于绝大多数编写程序的人来说,使用的编程语言称为“高级程序设计语言”,如C,C++ ,Java等。但由于计算机并不认识高级语言编写的程序,编好的程序需要通过编译变成计算机能够识别的机器语言程序,而这需要编译器和汇编器的帮助。其

2021-10-31 18:46:21 642

原创 页面更换算法

页面需要更换之前介绍了分页系统。它克服了交换系统的各种缺点:外部碎片、难以增长、程序不能大于物理内存。但是天下没有免费的午餐,既然优点如此之多,那总得付出点代价。这个代价就是页面的更换。在交换系统下,一个程序作为一个整体加载到内存。因此,在运行时,无需再从磁盘上加载任何东西。而在分页系统下,一个程序的所有页面并不一定都在内存中这样,在执行的过程中就可能发生页面不在内存的情况。如果访问的页面不在内存,则系统将产生缺页中断。缺页中断服务程序将负责把位于磁盘上的数据加载到物理内存来。如果物理内存还有空闲页面,

2021-10-31 15:06:41 615

原创 段式内存管理

分页系统的缺点前面一节阐述了分页内存管理它克服了交换系统的所有缺点,但它自己有缺点吗?页表太大?这个缺占用多级页表克服了。多级页表速度慢?这个问题用TLB解决了绝大部分。页面来回更换?这个缺点用页面更换算法解决了大部分。 固定页面大小呢?这不应该算是一个缺点,因为可变页面大小的操作系统不仅难以选择最优的页面大小,而且会变得很复杂。内部碎片算是一个小小的缺憾,但总比交换系统的外部碎片强,一个进程的内部碎片所浪费的空间平均起来只有半个页面,相对于分页系统的诸多优点来说,这个缺点似乎微不足道。那么分页系统还

2021-10-30 16:56:59 993 1

原创 页式内存管理

内存管理就是要将各种媒介组建成为一体,形成一个巨无霸似的虚拟存储系统。基址极限管理模式的问题到目前为止,已经讲述了几种基本的内存管理方法,分别是固定加载地址的内存管理、固定分区的内存管理、非固定分区的内存管理和交换内存管理,固定加载地址的内存管理只适合于单道编程,而其他三种则可用于多道编程。这三种适用于多道编程的内存管理模式均使用同一种实现机制:基址与极限基址与极限的工作原理是将程序发出的虚拟地址加上基址而获得物理地址!如果地址超过指定的极限,则视为地址出界而禁止访问,否则访问正常进行。在介绍过的三

2021-10-30 15:01:20 1764

原创 存储器的层次体系

计算机存储器的设计目标可归纳为三个问题:多大的容量?多快的速度?多贵的价格?“多大的容量”问题从某种意义上来说是无止境的,存储器有多大的容量,就可能开发出应用程序来使用它的容量。“多快的速度”问题相对易于回答,为达到最佳的性能,存储器的速度必须能够跟得上处理器的速度。换言之,当处理器正在执行指令时,我们不希望它会因为等待指令或操作数而暂停。“多贵的价格”问题也很重要。对一个实际的计算机系统,存储器的价格与计算机其他部件的价格相比应该是合理的。应该认识到,存储器的这三个重要特性即价格、容量和访问时间之间存

2021-10-29 21:45:31 1057

原创 基本内存管理

内存管理的环境程序要运行,必须先加载到内存。但在很久以前,准确地说是在操作系统出现以前,程序并不需要加载到内存才能运行。实际上,在那个已经久远的年代里,程序曾经是存放在卡片上,计算机每读一张卡片,就运行一条指令。因此,程序是直接从卡片到执行。但这种从外部存储媒介上直接执行指令的做法效率极低,且灵活性很差。因此,人们发明了内存储器来将需要运行的程序先行加载,再自动执行,从而提高效率和灵活性。这也导致了“存储的程序”概念,而存储的程序概念又导致计算机及软件系统的革命性变化。此后,人们对内存的要求是越来越多,

2021-10-29 19:48:20 940

原创 KMP算法

一种利用next数组加速字符串匹配的算法int KMP(string s1, string s2){ if (s1.size() < 1 || s2.size() > s1.size() || s2.size() == 0) { return -1; }//大过滤,不满足条件的没必要去进行匹配 else { int* nextval = new int[s2.size()]; get_nextval(nextval,s2);//O(N),先去获取下next的数组 i

2021-10-27 23:26:33 44

原创 树.(一)

树的定义树(tree)可以用几种方式定义。定义树的一种自然的方式是递归的方法。一棵树是一些结点的集合。这个集合可以是空集;若不是空集,则树由称作根(root)的结点r以及零个或多个非空的(子)树T,T2,…,T组成,这些子树中每一棵的根都被来自根r的一条有向的边(edge)所连接。每一棵子树的根叫作根r的儿子(child),而r是每一棵子树的根的父亲(parent)。从递归定义中可以发现,一棵树是N个结点和N-1条边的集合,其中的一个结点叫作根。存在N-1条边的结论是由下面的事实得出的:每条边都将某个

2021-10-27 20:07:34 109

原创 排序(三)

堆排序堆排序(Heap Sort)就是利用堆(假设利用大顶堆)进行排序的方法。它的基本思想是,将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次小值。如此反复执行,便能得到一个有序序列了。void Heapify(ElemType* arr, int size ,int pos = 0){ while (pos * 2 + 1 <

2021-10-26 17:50:48 71

原创 排序(二)

希尔排序谢尔排序使用一个序列h1, h2,… ,hi,叫作增量序列(increment sequence)。只要h= 1,任何增量序列都是可行的,不过,有些增量序列比另外一些增量序列更好。在使用增量h的一趟排序之后,对于每一个i我们有a[i]≤a[i +h],所有相隔h的元素都被排序。h排序的一般做法是,对于h, h+1,…,N-1中的每一个位置i,把其上的元素放到i, i -h, i-2h,…中间的正确位置上。虽然这并不影响最终结果,但是仔细的观察显示出,一趟h排序的作用就是对h个独立的子数组执行一次

2021-10-25 21:31:39 100

原创 排序(一)

排序的基本概念排序是我们生活中经常会面对的问题。同学们做操时会按照从矮到高排列;老师查看上课出勤情况时,会按学生学号顺序点名;高考录取时,会按成绩总分降序依次录取等。那排序的严格定义是什么呢?假设含有n个记录的序列为{r1,r2……rn},其相应的关键字分别为{k1,k2……,kn},需确定1,2,……,n的一种排列 p1,p2……pn,使其相应的关键字满足kp1≤kp2≤……≤kpn(非递减或非递增)关系,即使得序列成为一个按关键字有序的序列rp1,rp2……rpn},这样的操作就称为排序。这里关键

2021-10-24 16:36:42 70

小工具框架,electron+sqlite

小工具框架,electron+sqlite

2024-02-19

Sort_arr.hpp

一些基础的排序算法,C

2021-10-26

Stack_base_on_arr.hpp

基于数组的栈,C

2021-10-23

Stack_base_on_list.hpp

基于链表的栈,C

2021-10-23

Queue_base_on_list.hpp

基于链表的队列,C

2021-10-23

Queue_base_on_arr.hpp

基于数组的队列,C

2021-10-23

Deque_base_on_dulist.hpp

基于双向链表的双向队列,C

2021-10-23

Priority_Queue_on_arr.hpp

基于数组的优先队列,C

2021-10-23

Singly_Linked_List.hpp

简单的单链表,C

2021-10-22

Sqlist_base_on_list.hpp

基于链表的线性表实现,只有简单方法,不如链表那个,C语言

2021-10-22

Sqlist_base_on_arr.hpp

基于数组的线性表,只有一些基础方法,C语言

2021-10-22

贪吃蛇小游戏1.0(凑字数)

贪吃蛇小游戏1.0(凑字数)

2021-08-29

机房预约系统,初学C++.zip

机房预约系统,初学C++.zip

2021-08-19

演讲比赛,初步使用STL.zip

演讲比赛,初步使用STL.zip

2021-08-19

C++职工管理系统.rar

虚函数,仿动态数组

2021-07-20

C++基础应用———通讯录(链表).rar

应用C++基础做的通讯录(结构体+链表)

2021-07-17

扫雷小游戏1.0.cpp

自己做的简陋的扫雷小游戏,有些小BUG,有些冗余的部分

2021-06-24

操作系统进程调度(先到先服务,时间片)

操作系统实验代码

2021-05-20

操作系统小作业————动态分区分配代码

操作系统的动态分区分配代码

2021-05-18

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

TA关注的人

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