IO的分类:文件IO和标准IO
按存储类型:
文本文件:存储的是ASCII码(0~127),以EOF End Of File (-1)作为结束符。 一般存储数据量比较大的信息,读取的速度慢。
二进制文件:是数据在内存上的原样存储,存储的是二进制的形式。 一般存储中间变量,数据量比较小的信息,读取的速度快。
按操作方式:
带缓冲区的操作:(标准IO)高级的文件操作,系统会自动的在内存上给我们分配缓冲区。
不带缓冲区的操作:(文件IO)低级的文件操作,系统是不会自动的给我们的程序分配空间,但是如果需要 缓冲区的机制,缓冲区就得自己定义了。
标准IO和文件IO的区别:
标准IO: 1.标准IO是由库函数系统提供的,由ANSI C标准定义
2.是带缓冲区的操作,运行效率较高 3.支持跨平台的 4.标准IO操作的依据一般是流指针
文件IO: 1.文件IO是由操作系统提供的,由POSIX(可移植操作系统接口)定义
2.没有缓冲区,运行效率没有标准IO高
3.不支持跨平台的
4.文件IO操作的依据一般是文件描述符(非负整数)
系统调用和库函数:
系统调用:操作系统提供给用户直接操作硬件的一组接口 库函数:对系统调用的二次封装
区别:
1.系统调用一般提供基础的功能,库函数提供较为复杂的功能
2.系统调用一般不能重写,库函数可以重写
3.系统调用运行的时间属于机器时间,库函数运行时间属于用户时间
4.系统调用运行空间属于内核空间,库函数运行空间属于用户空间
5.系统调用的返回值一般是非负整数,库函数的返回值不一定
6.系统调用的运行效率没有库函数的高
7.系统调用的移植性没库函数的好
文件描述符和流指针:
文件描述符是一个非负整数,本质是数组下标
文件流指针:
标准IO缓存区的方式:全缓冲和行缓冲
全缓冲:缓冲区满了才刷新缓冲区,或者强制刷新缓冲区.
行缓冲:碰到换行符刷新缓冲区、缓冲区满了刷新、或者强制刷新缓冲区。
不缓冲:所有信息到缓冲区后直接到文件。
对文件进行操作
打开文件:fopen
操作文件:fputc和fgetc,功能分别是从stream指示的文件中读取字符,给stream写了一个字符c。
以行读写:fgets和fputs 以对象读写:fread和fwrite
以格式化读写:fprintf和fscanf,功能分别为往指定流里输出东西和往指定流里输入东西。
fclose是关闭文件;fflsh功能是强制刷新由参数指定的流;feof判断文件是否到末尾。
time()函数:
这里简单的输出一个实时时间举例:
光标移动:fseek 获取光标位置:ftell
案例演示:创造一个空洞空间
fileno:获取文件流指针里面的文件描述符
动态库和静态库:
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库,因此体积较大。 动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动 态库存在,因此代码体积较小。
数据结构:
存储结构
顺序,链式,索引,哈希存储
1.顺序存储:在逻辑上相邻的元素,在物理空间上也相邻
优点:查找方便, 存储空间的利用率可以达到1
缺点:插入和删除不方便, 申请空间的时候,必须是一片连续的空间,对空间的要求比较高 会用空间碎片的产生 。
2.链式存储:在逻辑上相邻的元素,在物理空间上不一定相邻 。
优点:插入元素不需要移动大量的空间 对空间的要求没那么大,。
缺点:查找不方便 存储空间的利用率不足1,没有顺序存储的大 。
3.索引存储:依据索引表查找数据大概位置,详细查找数据本身(冲突没有解决号的哈希存储)
优点:查找方便
缺点:有索引表的存在,要浪费空间 插入元素,删除元素之后,索引表要更新
4.哈希存储:根据关键字直接就能定位到记录本身,就能拿到数据 优点:查找方便,插入,删除也方便 缺点:如果哈希函数设计的不合理,查找的效率就会很低
顺序表的定义:
线性结构的链式存储:
链表的分类: 按方向分:单链表、双链表; 按是否循环分:循环链表,不循环链表;按是否带头节点:带头结点的链表,不带头结点的链表 。
链表图解:
销毁单链表:
按找头删、尾删的原则,把所有的数据节点全部删除(free) 当只剩下头节点的时候再释放头节点。
线性表,链表,顺序之间的区别:
线性表是一种逻辑结构 顺序表和链表是线性表在顺序存储下和链式存储下的体现。
链表和顺序表的区别:
1.链表是链式存储,顺序表是顺序存储
2.顺序表会有空间碎片产生,链表没有空间碎片产生
3.链表一般多用于插入、删除较多的场景 顺序表一般用于查找较多的场景 。
4.顺序表的存储空间利用率比链表的大。
链表和顺序表怎么选择?
1.从空间来说 顺序表对空间的要求比链表大,顺序表的利用率比链表大。
2.从操作来说 多用于查找,用顺序表 多用于插入、删除,用链表。
3.从编译环境来说 不支持指针类型操作的编译器不能使用链表。
栈与队列:
栈受限在操作上:只允许数据在一段进行插入和删除操作,允许操作的一段叫做栈顶 特点:先进后出(FILO),
队列:只允许在一段执行插入操作,另一端执行删除操作,允许插入的一段叫做队尾,允许删除操作的一段叫做队头 特点:先进先出(FIFO)。
串受限在存储上:只允许存储字符 * ' a — 1
避免假队空的方法:
1.舍弃一片空间 head = (tail+1)%SIZE
2.另外设置一个变量 count == SIZE;
3.设置标志位记录上次执行的操作是入队还是出队 head == tail && flag == 1
树
树的相关概念:
度数: 一个节点的子树的个数称为该节点的度数,一棵树的度数是指该树中节点的最大度数。
高度(层数、深度): 节点的层数等于父节点的层数加一,根节点的层数定义为一。树中节点层数的最大值称为该树的高度或深度。
路径:边数: 一个节点系列k1,k2, ……,ki,ki+1, ……,kj,并满足ki是ki+1的父节点,就称为一条从k1到kj的路径,路径的 长度为j-1,即路径中的边数。路径中前面的节点是后面节点的祖先,后面节点是前面节点的子孙。
叶子节点: 度数为0的结点
二叉树的定义:
二叉树(Binary Tree)是n(n≥0)个节点的有限集合,它或者是空集(n=0),或者是由一个 根节点以及两棵互不相交的、分别称为左子树和右子树的二叉树组成。二叉树与普通有序树不同,二叉树严格区分 左孩子和右孩子,即使只有一个子节点也要区分左右。
树结点的遍历:先序,中序和后序
赫夫曼树:
赫夫曼(Huffman)树,又称最优树,是带权路径长度最短的树,有着广泛的应用 从树中一个结点到另外一个结点的分支构成一条路径,分支的数目称为路径的长度。树的路径长度是指从树根到每 个结点的路径长度之和 进一步推广,考虑带权的结点。结点的带权路径长度指的是从树根到该结点的路径长度和结点上权的乘积。树的带 权路径长度是指所有叶子节点的带权路径长度之和,记作 WPL 。WPL最小的二叉树就是最优二叉树,又称为赫夫曼树
线索二叉树: