基础准备
Posted wyctstf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础准备相关的知识,希望对你有一定的参考价值。
前情提要:
蒟蒻于2019-1-29开始学习数据结构,开此系列作为学习后的整理。
当然,蒟蒻的学习主要还是来自[MOOC](https://www.icourse163.org/?from=study)上的数据结构一课
数据结构没有标准定义(相关定义网上有很多),但它与算法有着密切联系
在听课后,主要通过三个例子,讲了三个简单结论:
- 解决问题方法的效率, 跟数据的组织方式有关(例如放书本的问题,可以按字典序放,分类别放)
- 解决问题方法的效率, 跟空间的利用效率有关(同样输出1-n,递归和循环实现所占空间对比,主要因为递归用到了栈)
- 解决问题方法的效率, 跟算法的巧妙程度有关(同样计算多项式的和,普通办法和秦九韶算法对比)
关于数据对象组织方式:
- 物理结构
- 逻辑结构
数据结构可以用抽象数据类型来描述
数据类型:
- 数据对象集
- 数据集合相关联的操作集
抽象:
1. 与存放数据的机器无关
1. 与数据存储的物理结构无关
1. 与实现操作的算法和编程语言均无关
只描述数据对象集和相关操作集**“是什么”**,而不涉及**如何做到**的问题
举个栗子:
矩阵抽象数据类型定义:
类型名称:
矩阵
数据对象集:
一个M*N的矩阵由M*N个三元组< a , i , j >构成, a 为矩阵元素的值, i 为元素所在行号, j 为元素所在列号
操作集:
- Matrix Create( int M , int N ):返回一个M*N的空矩阵
- int Getmaxrow( Maxtrix A ):返回矩阵A的总行数
- int GetMaxCol( Maxtrix A ):返回矩阵A的总列数
- ElementType Getentry( Maxtrix A , int i , int j ):返回矩阵A的第 i 行,第 j 列的元素
- Matirx Add( Matrix A , Matrix B ):如果 A 、B行列数一致,就返回 C = A + B,否则返回错误标志
- Matrix Multiply( Matrix A , Matrix B ):如果 A 的列数等于 B 的行数,就返回 C = A + B ,否则返回错误标志
在上述数据类型中,我们只要知道矩阵和相关操作集,矩阵可以按什么类型存储(二维数组?一维数组?十字链表?),矩阵元素的类型ElementType(int?char?bool?),操作的实现(最后两个操作是按行加?按列加?什么语言?)等等具体实现没有限制
补充:
秦九韶算法:
针对任何一个一元多项式,都可以写成:
f(x)=a[0]+a[1]x+...+a[n-1]x^n-1+a[n]x^n
最直接的办法是根据多项式的标准表达式
f(x)=∑ n<---i=0 a[i]x[i]循环累计求和得到结果
而秦九韶算法计算时:f(x) = a0 + x( a1 + x(...( a[n - 1] + x ( a [n] ) )... ) )
#### clock()工具的使用:
引申两个概念:
clock():捕捉从程序开始运行到clock()被调用时所耗费的时间。这个 时间单位是clock tick,即“时钟打点”。
常数CLK_TCK(或CLOCKS_PER_SEC):机器时钟每秒所走的时钟打点数。
程序实现:
#include <stdio.h> #include <time.h> clock_t start, stop; /* clock_t是clock()函数返回的变量类型 */ double duration; /* 记录被测函数运行时间,以秒为单位 */ int main () { /* 不在测试范围内的准备工作写在clock()调用之前*/ start = clock();/* 开始计时 */ MyFunction();/* 把被测函数加在这里 */ stop = clock();/* 停止计时 */ duration = ((double)(stop - start))/CLK_TCK; /* 计算运行时间 */ /* 其他不在测试范围的处理写在后面,例如输出duration的值 */ return 0; }
算法(algorithm)
- 一个有限指令集
- 接受一些输入(有些情况下不需要输入)
- 产生输出
- 一定在有限步骤之后终止
- 每一条指令必须
- 有充分明确的目标,不可以有歧义
- 计算机能处理的范围之内
- 描述应不依赖于任何一种计算机语言以及具体的实现手段
衡量一个算法——算法复杂度:
- 时间复杂度:
- 根据算法写成的程序在执行时 耗费时间的长度。这个长度往往也与输入数据的规模有关。
- 一般我们描述时间复杂度时采用它的最坏时间复杂度,而非平均时间复杂度,因为这个平均难以确定
- 空间复杂度
根据算法写成的程序在执行时占用存储单元的长度。空间复杂度过高的算法可能导致使用的内存超限,造成程序非正常中断
复杂度的渐进表示法:
- T( n ) = O ( f ( n ) ) 表示存在常数C>0, n0>0 使得当n>=n0 时有T(n) <= C·f(n)
- T( n ) = ?( g ( n ) ) 表示存在常数C>0, n0>0 使得当n>=n0 时有T(n)>=C·g(n)
- T( n ) = Θ( h ( n ) ) 表示同时有T(n)=O(h(n))和T(n) = ?(h(n))
复杂度分析小窍门:
若两段算法分别有复杂度T1(n) = O(f1(n)) 和T2(n) = O(f2(n)),则:
- T1(n) + T2(n) = max( O(f1(n)), O(f2(n)) )
- 若T(n)是关于n的k阶多项式,那么T(n)=Θ(nk)
- 一个for循环的时间复杂度等于循环次数乘以循环体 代码的复杂度
- if-else 结构的复杂度取决于if的条件判断复杂度 和两个分枝部分的复杂度,总体复杂度**取三者中最大**
以上是蒟蒻搬到cnblog的第一篇博客(为什么cnblog不用markdown呢?)
以上是关于基础准备的主要内容,如果未能解决你的问题,请参考以下文章
JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段
[Go] 通过 17 个简短代码片段,切底弄懂 channel 基础