数据结构-绪论(第一章)的整理笔记,若有错误,欢迎指正。
框架图
数
据
结
构
{
三
要
素
{
逻
辑
结
构
{
线
性
结
构
{
一
对
一
的
关
系
除
第
一
个
元
素
,
其
余
都
有
唯
一
前
驱
除
最
后
一
个
元
素
,
其
余
都
有
唯
一
后
继
}
(
如
:
线
性
表
、
栈
、
队
列
、
数
组
、
串
)
非
线
性
结
构
{
树
形
结
构
:
一
对
多
的
关
系
图
形
结
构
:
多
对
多
的
关
系
}
(
如
:
二
维
/
多
维
数
组
、
广
义
表
、
树
、
图
)
存
储
结
构
{
顺
序
存
储
结
构
链
式
存
储
结
构
索
引
存
储
结
构
哈
希
存
储
结
构
}
非
顺
序
存
储
结
构
数
据
的
运
算
{
运
算
描
述
运
算
实
现
数
据
类
型
{
原
子
类
型
:
值
不
可
再
分
(
如
:
整
型
、
字
符
型
)
结
构
类
型
:
值
可
以
再
分
解
(
如
:
结
构
体
)
抽
象
数
据
类
型
算
法
{
算
法
的
五
个
特
征
{
有
穷
性
:
有
限
步
之
后
结
束
,
有
限
时
间
内
完
成
确
定
性
:
相
同
的
输
入
只
能
对
应
相
同
的
输
出
可
行
性
:
可
通
过
有
限
次
执
行
输
出
某
个
结
果
输
入
:
零
个
或
多
个
输
出
:
一
个
或
多
个
好
算
法
的
特
质
{
正
确
性
:
输
出
正
确
的
结
果
,
能
解
决
实
际
问
题
可
读
性
:
便
于
更
好
的
理
解
健
壮
性
:
输
入
非
法
数
据
时
,
能
够
适
当
做
出
反
应
或
进
行
处
理
高
效
率
与
低
存
储
量
需
求
:
执
行
速
度
快
并
且
不
费
内
存
算
法
描
述
{
输
入
型
参
数
的
描
述
输
出
型
参
数
的
描
述
算
法
分
析
{
时
间
复
杂
度
分
析
空
间
复
杂
度
分
析
递
归
算
法
的
时
、
空
分
析
数
据
结
构
+
算
法
=
程
序
{
数
据
结
构
和
算
法
的
关
系
算
法
和
程
序
的
关
系
从
数
据
结
构
角
度
求
解
问
题
的
步
骤
数据结构\begin{cases} 三要素\begin{cases} 逻辑结构\begin{cases} 线性结构\left. \begin{array}{l} \begin{cases} 一对一的关系 \\ 除第一个元素,其余都有唯一前驱 \\ 除最后一个元素,其余都有唯一后继 \\ \end{cases}\\ \end{array} \right\}(如:线性表、栈、队列、数组、串)\\ 非线性结构 \left. \begin{array}{l}\begin{cases} 树形结构:一对多的关系 \\ 图形结构:多对多的关系 \\ \end{cases} \\ \end{array} \right\} (如:二维/多维数组、广义表、树、图) \end{cases} \\ 存储结构\begin{cases} \;\;\;顺序存储结构 \\ \left. \begin{array}{l} \ 链式存储结构 \\ \ 索引存储结构 \\ \ 哈希存储结构 \\ \end{array} \right\} 非顺序存储结构 \end{cases} \\ 数据的运算\begin{cases} 运算描述 \\ 运算实现 \\ \end{cases} \\ \end{cases} \\ 数据类型\begin{cases} 原子类型:值不可再分(如:整型、字符型) \\ 结构类型:值可以再分解(如:结构体) \\ 抽象数据类型 \\ \end{cases} \\ 算法\begin{cases} 算法的五个特征\begin{cases} 有穷性:有限步之后结束,有限时间内完成 \\ 确定性:相同的输入只能对应相同的输出 \\ 可行性:可通过有限次执行输出某个结果 \\ 输入:零个或多个 \\ 输出:一个或多个 \\ \end{cases} \\ 好算法的特质\begin{cases} 正确性:输出正确的结果,能解决实际问题 \\ 可读性:便于更好的理解 \\ 健壮性:输入非法数据时,能够适当做出反应或进行处理 \\ 高效率与低存储量需求:执行速度快并且不费内存 \\ \end{cases} \\ 算法描述\begin{cases} 输入型参数的描述 \\ 输出型参数的描述 \\ \end{cases} \\ 算法分析\begin{cases} 时间复杂度分析 \\ 空间复杂度分析 \\ 递归算法的时、空分析 \\ \end{cases} \\ \end{cases} \\ 数据结构+算法=程序\begin{cases} 数据结构和算法的关系 \\ 算法和程序的关系 \\ 从数据结构角度求解问题的步骤 \\ \end{cases} \end{cases}
数据结构⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧三要素⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧逻辑结构⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧线性结构⎩⎪⎨⎪⎧一对一的关系除第一个元素,其余都有唯一前驱除最后一个元素,其余都有唯一后继⎭⎪⎬⎪⎫(如:线性表、栈、队列、数组、串)非线性结构{树形结构:一对多的关系图形结构:多对多的关系}(如:二维/多维数组、广义表、树、图)存储结构⎩⎪⎪⎨⎪⎪⎧顺序存储结构 链式存储结构 索引存储结构 哈希存储结构⎭⎬⎫非顺序存储结构数据的运算{运算描述运算实现数据类型⎩⎪⎨⎪⎧原子类型:值不可再分(如:整型、字符型)结构类型:值可以再分解(如:结构体)抽象数据类型算法⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧算法的五个特征⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧有穷性:有限步之后结束,有限时间内完成确定性:相同的输入只能对应相同的输出可行性:可通过有限次执行输出某个结果输入:零个或多个输出:一个或多个好算法的特质⎩⎪⎪⎪⎨⎪⎪⎪⎧正确性:输出正确的结果,能解决实际问题可读性:便于更好的理解健壮性:输入非法数据时,能够适当做出反应或进行处理高效率与低存储量需求:执行速度快并且不费内存算法描述{输入型参数的描述输出型参数的描述算法分析⎩⎪⎨⎪⎧时间复杂度分析空间复杂度分析递归算法的时、空分析数据结构+算法=程序⎩⎪⎨⎪⎧数据结构和算法的关系算法和程序的关系从数据结构角度求解问题的步骤
四种数据存储结构的优缺点对比
存储结构 | 简介 | 优点 | 缺点 |
---|---|---|---|
顺序存储 | 把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现 | 可以实现随机存取,每个元素占用最少的存储空间(存储效率高) | 只能使用相邻的一整块存储单元, 因此可能产生较多的外部碎片;不便于数据修改,对元素的插入或删除操作可能要移动一系列的元素 |
链式存储 | 不要求逻辑上相邻的元素在物理位置上也相邻,借助指示元素存储地址的指针来表示元素之间的逻辑关系 | 不会出现碎片现象,能充分利用所有存储单元;便于修改数据,插入或删除操作时仅需修改相应结点的指针域,不必移动结点 | 每个元素因存储指针而占用额外的存储空间,且只能实现顺序存取 |
索引存储 | 在存储元素信息的同时,还建立附加的索引表。索引表中的每项称为索引项,索引项的一般形式是(关键字,地址) | 检索速度快,查找效率高 | 附加的索引表额外占用存储空间 |
散列存储 | 根据元素的关键字直接计算出该元素的存储地址,又称哈希(Hash) 存储 | 检索、增加和删除结点的操作都很快 | 若散列函数不好,则可能出现元素存储单元的冲突,而解决冲突会增加时间和空间开销 |
- 顺序存储
- 不便于数据修改,对元素的插入或删除操作可能需要移动一系列的元素,逻辑上连续的元素在存储位置上也连续。
- 链式存储
- 便于修改数据,对元素进行插入或删除操作时,修改相应结点的指针域即可。逻辑上连续的元素在存储位置上可以不连续。
- !链式存储设计时,结点内的存储单元地址一定连续。不同结点的存储空间可以不连续。
- 索引存储
- 通过创建索引表,利用关键字的有序性可以快速查找到该关键字的地址,从而找到对应元素。逻辑上连续的元素在物理上可以不连续。
-
数据与数据元素的区别与联系
数据:是信息的载体,能被计算机程序识别和处理(数字、字符、图像等),是一个集合。
数据元素:是组成数据的基本单位,是数据的个体。
联系:数据元素与数据的关系是元素与集合的关系。 -
数据逻辑结构与存储结构的区别与联系
区别:在数据结构中,逻辑结构指数据元素之间的逻辑关系,它与数据的存储无关,独立于计算机,而存储结构是数据元素之间的逻辑关系在计算机中的表示,它依赖于计算机。
联系:逻辑结构和存储结构都属于数据结构三要素之一,存储结构不仅要将逻辑结构中的所有数据元素存储到计算内存中,而且还要在内存中存储各数据元素间的逻辑关系。通常情况下,一种逻辑结构可以有多种存储结构,例如线性结构可以采用顺序存储结构或链式存储结构表示。
!数据的存储结构会影响存储空间分配的方便程度以及数据运算的速度 -
数据结构、数据类型、抽象数据结构的区别
数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。在任何问题中,数据元素都不是孤立存在的,它们之间存在某种关系,这种数据元素相互之间的关系成为结构(Structure)。
数据类型: 是一个值的集合+定义在此集合上的一组操作的总称。
例:bool类型,它是逻辑型变量的定义符,取值为true或false(值的集合)。
可进行逻辑与(&&)、逻辑或(||)、逻辑非(!)的运算(定义在此集合上的操作)。
抽象数据类型(ADT):是一个数学模型+定义在模型上的一组操作。由用户定义,用以表示应用问题的数据模型。它由基本的数据类型构成,与数据类型实质上是一个概念,但它的特征是使用与实现分离,实行封装和信息隐蔽(独立于计算机)。
抽象数据类型=逻辑结构+抽象运算,通常用(数据对象,数据关系,基本操作集)这样的三元组来表示,从而构成一个完整的数据结构定义。 -
运算描述和运算实现的区别与联系
联系:运算描述和运算实现都属于数据的运算,而数据的运算又属于数据结构三要素之一。运算描述和运算实现都能完成对数据的“处理"或某种特定的操作。
区别:运算描述是指逻辑结构施加的操作,它只是描述处理功能,不包括处理步骤和方法,而运算实现是指一个完成该运算功能的算法,它的核心是设计处理步骤。 -
时间复杂度
①加法规则
T ( n ) = T 1 ( n ) + T 2 ( n ) = O ( f ( n ) ) + O ( g ( n ) ) = O ( m a x f ( n ) , g ( n ) ) T(n)=T_1(n)+T_2(n) =O(f(n))+O(g(n))=O(max f(n),g(n)) T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(maxf(n),g(n))
!多项相加,只保留最高阶的项,且系数变为1
例: T ( n ) = 3 n 3 + n 2 ⇒ O ( n 3 ) T(n)=3n^3 +n^2 \Rightarrow O(n^3) T(n)=3n3+n2⇒O(n3)
②乘法规则
T ( n ) = T 1 ( n ) × T 2 ( n ) = O ( f ( n ) ) × O ( g ( n ) ) = O ( f ( n × g ( n ) ) T(n)=T_1(n)×T_2(n)=O(f(n))×O(g(n))=O (f(n×g(n)) T(n)=T1(n)×T2(n)=O(f(n))×O(g(n))=O(f(n×g(n))
!多项相乘,都保留
例: T ( n ) = n 2 ⋅ l o g 2 n ⇒ O ( n 2 l o g 2 n ) T(n)=n^2\cdot log_2^n \Rightarrow O(n^2log_2^n) T(n)=n2⋅log2n⇒O(n2log2n)
!若同时含有加法和乘法,则要进行比较
例: T ( n ) = n 3 + n 2 l o g 2 n = n 2 ⋅ n + n 2 ⋅ n l o g 2 n T(n)=n^3+n^2log_2^n=n^2\cdot n+n^2\cdot nlog_2^n T(n)=n3+n2log2n=n2⋅n+n2⋅nlog2n,而 O ( l o g 2 n ) < O ( n ) ⇒ O ( n 3 ) O(log_2^n)<O(n) \Rightarrow O(n^3) O(log2n)<O(n)⇒O(n3)
常见的几种时间复杂度的顺序为:
O ( 1 ) < O ( l o g 2 n ) < O ( n ) < O ( n l o g 2 n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1)<O(log_2^n)<O(n)<O(nlog_2^n)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n) O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)
几种常见的时间复杂度的相关曲线如图:
推导(洛必达法则):
① O ( l o g 2 n ) < O ( n ) O(log_2^n)<O(n) O(log2n)<O(n) lim n → ∞ l o g 2 n n ⇒ lim n → ∞ 1 n ⋅ l n 2 = 0 \lim_{n \to \infty} \frac{log_2^n}{n}\Rightarrow \lim_{n \to \infty} \frac{1}{n\cdot ln2}=0 n→∞limnlog2n⇒n→∞limn⋅ln21=0
(当 n → ∞ n\rightarrow\infty n→∞, n n n比 l o g 2 n log_2^n log2n变大的速度快很多)
② O ( n 2 ) < O ( 2 n ) O(n^2)<O(2^n) O(n2)<O(2n) lim n → ∞ n 2 2 n ⇒ lim n → ∞ 2 n 2 n ⋅ l n 2 ⇒ lim n → ∞ 2 2 n ⋅ l n 2 2 = 0 \lim_{n \to \infty} \frac{n^2}{2^n}\Rightarrow \lim_{n \to \infty} \frac{2n}{2^n\cdot ln2}\Rightarrow \lim_{n \to \infty} \frac{2}{2^n\cdot ln^22}=0 n→∞lim2nn2⇒n→∞lim2n⋅ln22n⇒n→∞lim2n⋅ln222=0 -
时间复杂度例题
例①
void fun(int n){
int i=1;
while(i<=n)
i=i*2;
}
!第1次循环:
i
=
2
=
2
1
i=2=2^1
i=2=21;第2次循环:
i
=
4
=
2
2
i=4=2^2
i=4=22;第3次循环:
i
=
8
=
2
3
i=8=2^3
i=8=23…第t次循环:
i
=
2
=
2
t
i=2=2^t
i=2=2t,当
i
>
n
i>n
i>n时循环结束。
2
t
≤
n
2^t\leq n
2t≤n,即
t
≤
l
o
g
2
n
t\leq log_2^n
t≤log2n。因此时间复杂度
T
(
n
)
=
O
(
l
o
g
2
n
)
T(n)=O(log_2^n)
T(n)=O(log2n)。
例②
int fact(int n){
if(n<=1) return 1;
return n*fact(n-1);//求整数n(n大于等于0)的阶乘
}
!递归代码,每次递归调用时,fact()的参数减1,递归出口为fact(1),一共执行n次递归调用。
因此时间复杂度
T
(
n
)
=
O
(
n
)
。
T(n)=O(n)。
T(n)=O(n)。
例③
count=0;
for(k=1;k<=n;k*=2)
for(j=1;j<=n;j++)
count++;
!外层循环参见例①,时间复杂度
T
1
(
n
)
=
O
(
l
o
g
2
n
)
T_1(n)=O(log_2^n)
T1(n)=O(log2n),外层循环(1~n)共循环
n
n
n次,时间复杂度
T
2
(
n
)
=
O
(
n
)
T_2(n)=O(n)
T2(n)=O(n)
乘法规则,
T
(
n
)
=
T
1
(
n
)
×
T
2
(
n
)
=
O
(
l
o
g
2
n
)
×
O
(
n
)
=
O
(
n
l
o
g
2
n
)
T(n)=T_1(n)×T_2(n)=O(log_2^n)×O(n)=O (nlog_2^n)
T(n)=T1(n)×T2(n)=O(log2n)×O(n)=O(nlog2n)
例④
int func(int n){
int i=0,sum=0;
while(sum<n) sum += ++i;
return i;
}
!第1次循环:
s
u
m
=
0
+
1
=
1
sum=0+1=1
sum=0+1=1;第2次循环:
s
u
m
=
1
+
2
=
3
sum=1+2=3
sum=1+2=3;第3次循环:
s
u
m
=
3
+
3
=
6
sum=3+3=6
sum=3+3=6…第t次循环:
s
u
m
=
0
+
1
+
2
+
⋯
+
t
sum=0+1+2+\cdots+t
sum=0+1+2+⋯+t,当
s
u
m
≥
n
sum\geq n
sum≥n时循环结束。
(
0
+
t
)
(
t
+
1
)
2
<
n
\frac{(0+t)(t+1)}{2}<n
2(0+t)(t+1)<n,因此时间复杂度
T
(
n
)
=
O
(
n
)
T(n)=O(\sqrt n)
T(n)=O(n)。
例⑤
void fun(int n){
int i=0;
while(i*i*i<n){
i++;
}
!第1次循环:判断
1
3
<
n
?
1^3<n?
13<n?;第2次循环:判断
2
3
<
n
?
2^3<n?
23<n?;第3次循环:判断
3
3
<
n
?
3^3<n?
33<n?…第t次循环:判断
t
3
<
n
?
t^3<n?
t3<n?,当
t
3
≥
n
t^3\geq n
t3≥n时循环结束。
t
3
<
n
t^3<n
t3<n,因此时间复杂度
T
(
n
)
=
O
(
n
3
)
T(n)=O(\sqrt[3]{n})
T(n)=O(3n)
例⑥
for(i=n-1;i>1;i--)
for(j=1;j<i;j++)
if(a[j]>a[j+1])
a[j]与a[j+1]交换;
//其中n为整数,则最后一行语句的频度在最坏情况下是?
!最坏情况下为:每一次都进行交换
T
(
n
)
=
∑
i
=
2
n
−
1
∑
j
=
1
i
−
1
1
=
∑
i
=
2
n
−
1
(
i
−
1
)
[
累
加
上
标
−
累
加
下
标
+
1
=
(
i
−
1
)
−
1
+
1
]
=
[
1
+
(
n
−
2
)
]
(
n
−
2
)
2
(
[
首
项
+
末
项
]
×
项
数
2
)
(
首
项
将
i
=
2
带
入
,
末
项
将
n
−
1
带
入
,
项
数
为
:
累
加
上
标
−
累
加
下
标
+
1
)
\begin{aligned} T(n) & =\sum_{i=2}^{n-1}\sum_{j=1}^{i-1}1 \\ & =\sum_{i=2}^{n-1}(i-1)\;\;\;[累加上标-累加下标+1=(i-1)\bcancel{-1}\bcancel{+1}] \\ & =\frac{[1+(n-2)](n-2)}{2}\;\;\;\;(\frac{[首项+末项]×项数}{2}) \\ & (首项将i=2带入,末项将n-1带入,项数为:累加上标-累加下标+1)\\ \end{aligned}
T(n)=i=2∑n−1j=1∑i−11=i=2∑n−1(i−1)[累加上标−累加下标+1=(i−1)−1
+1
]=2[1+(n−2)](n−2)(2[首项+末项]×项数)(首项将i=2带入,末项将n−1带入,项数为:累加上标−累加下标+1)
因此时间复杂度
T
(
n
)
=
O
(
n
2
)
T(n)=O(n^2)
T(n)=O(n2)
例⑦
void fun(int n)
{ int s=0,i,j,k;
for(i=0;i<=n;i++)
for(j=0;j<=i;j++)
for(k=0;k<j;k++)
s++;
}
T
(
n
)
=
∑
i
=
0
n
∑
j
=
0
i
∑
k
=
0
j
−
1
1
=
∑
i
=
0
n
∑
j
=
0
i
j
=
∑
i
=
0
n
(
0
+
i
)
⋅
(
i
+
1
)
2
=
1
2
(
∑
i
=
0
n
i
2
+
∑
i
=
0
n
i
)
=
1
2
(
n
(
n
+
1
)
(
n
+
2
)
6
+
n
(
n
+
1
)
2
)
=
2
n
3
+
6
n
2
+
4
n
12
\begin{aligned} T(n) & =\sum_{i=0}^{n}\sum_{j=0}^{i}\sum_{k=0}^{j-1}1 \\ & =\sum_{i=0}^{n}\sum_{j=0}^{i}j \\ & =\sum_{i=0}^{n}\frac{(0+i)\cdot (i+1)}{2} \\ & =\frac{1}{2}(\sum_{i=0}^{n}i^2+\sum_{i=0}^{n}i) \\ & =\frac{1}{2}(\frac{n(n+1)(n+2)}{6}+\frac{n(n+1)}{2}) \\ & =\frac{2n^3+6n^2+4n}{12} \\ \end{aligned}
T(n)=i=0∑nj=0∑ik=0∑j−11=i=0∑nj=0∑ij=i=0∑n2(0+i)⋅(i+1)=21(i=0∑ni2+i=0∑ni)=21(6n(n+1)(n+2)+2n(n+1))=122n3+6n2+4n
因此时间复杂度
T
(
n
)
=
O
(
n
3
)
T(n)=O(n^3)
T(n)=O(n3)
例⑧
void fun(int n)
{ int i,j,k;
for(i=0;i<n;i++) //语句①
for(j=0;j<n;j++) //语句②
{ c[i][j]=0; //语句③
for(k=0;k<n;k++) //语句④
c[i][j]=c[i][j]+a[i][k]*b[k][i]; //语句⑤
}
}
//分析语句①~⑤的频度
!
语句①:循环控制变量i要从0增加到n,测试i=n时才会终止。故它的频度是n+1。
语句②:语句②作为语句①循环体内的语句应该只执行n次,但语句②本身也要执行n+1次(原因同语句①)。
∑
i
=
0
n
−
1
(
n
+
1
)
=
n
(
n
+
1
)
\sum_{i=0}^{n-1}(n+1)=n(n+1)
i=0∑n−1(n+1)=n(n+1)
语句③: 语句③作为语句②循环体内的语句应该只执行n次,而语句③本身也要执行n次。
∑
i
=
0
n
−
1
∑
j
=
0
n
−
1
1
=
n
2
\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}1=n^2
i=0∑n−1j=0∑n−11=n2
语句④:
∑
i
=
0
n
−
1
∑
j
=
0
n
−
1
(
n
+
1
)
=
n
3
+
n
2
\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}(n+1)=n^3+n^2
i=0∑n−1j=0∑n−1(n+1)=n3+n2
语句⑤:
∑
i
=
0
n
−
1
∑
j
=
0
n
−
1
∑
k
=
0
n
−
1
1
=
n
3
\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}\sum_{k=0}^{n-1}1=n^3
i=0∑n−1j=0∑n−1k=0∑n−11=n3
语句①的频度:
n
+
1
n+1
n+1
语句②的频度:
n
(
n
+
1
)
n(n+1)
n(n+1)
语句③的频度:
n
2
n^2
n2
语句④的频度:
n
3
+
n
2
n^3+n^2
n3+n2
语句⑤的频度:
n
3
n^3
n3