Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
think-dast-zh
提交
7d418498
T
think-dast-zh
项目概览
OpenDocCN
/
think-dast-zh
8 个月 前同步成功
通知
0
Star
26
Fork
13
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
think-dast-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
7d418498
编写于
9月 03, 2017
作者:
W
wizardforcel
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ch3.
上级
b3318859
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
20 addition
and
0 deletion
+20
-0
3.md
3.md
+20
-0
未找到文件。
3.md
浏览文件 @
7d418498
...
...
@@ -144,3 +144,23 @@ public boolean add(E element) {
这种划分算法的方式,通过计算一系列调用中的平均时间,称为摊销分析。你可以在
<http://thinkdast.com/amort>
上阅读更多信息。重要的想法是,复制数组的额外成本是通过一系列调用展开或“摊销”的。
现在,如果
`add(E)`
是常数时间,那么
`add(int, E)`
呢?调用
`add(E)`
后,它遍历数组的一部分并移动元素。这个循环是线性的,除了在列表末尾添加的特殊情况中。因此,
`add(int, E)`
是线性的。
## 3.3 问题规模
最后一个例子中,我们将考虑
`removeAll`
,这里是
`MyArrayList`
中的实现:
```
java
public
boolean
removeAll
(
Collection
<?>
collection
)
{
boolean
flag
=
true
;
for
(
Object
obj:
collection
)
{
flag
&=
remove
(
obj
);
}
return
flag
;
}
```
每次循环中,
`removeAll`
都调用
`remove`
,这是线性的。所以认为
`removeAll`
是二次的很诱人。但事实并非如此。
在这种方法中,循环对于每个
`collection`
中的元素运行一次。如果
`collection`
包含
`m`
个元素,并且我们从包含
`n`
个元素的列表中删除,则此方法是
`O(nm)`
的。如果
`collection`
的大小可以认为是常数,
`removeAll`
相对于
`n`
是线性的。但是,如果集合的大小与
`n`
成正比,
`removeAll`
则是平方的。例如,如果
`collection`
总是包含
`100`
个或更少的元素,
`removeAll`
则是线性的。但是,如果
`collection`
通常包含的列表中的 1% 元素,
`removeAll`
则是平方的。
当我们谈论问题规模时,我们必须小心我们正在讨论哪个大小。这个例子演示了算法分析的陷阱:对循环计数的诱人捷径。如果有一个循环,算法往往是 线性的。如果有两个循环(一个嵌套在另一个内),则该算法通常是平方的。不过要小心!你必须考虑每个循环运行多少次。如果所有循环的迭代次数与
`n`
成正比,你可以仅仅对循环进行计数之后离开。但是,如在这个例子中,迭代次数并不总是与
`n`
成正比,所以你必须考虑更多。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录