通过例子看世界
你的博客有很多文章,每篇文章都有阅读量,
你要将这个列表按照阅读数量由多到少排序。
文章名 | 阅读量 |
---|---|
钢铁是怎样炼成的 | 110 |
钻石是怎样炼成的 | 30 |
铜是怎样炼成的 | 60 |
初级程序员是怎样炼成的 | 302 |
中级程序员是怎样炼成的 | 214 |
高级程序员是怎样炼成的 | 584 |
选择排序法
遍历这个列表,找出阅读数最多的文章,将该文章添加到一个新列表中;
第一次遍历
原文章变为下表,将最多的“高级程序员是怎样炼成的”文章移除
文章名 | 阅读量 |
---|---|
钢铁是怎样炼成的 | 110 |
钻石是怎样炼成的 | 30 |
铜是怎样炼成的 | 60 |
初级程序员是怎样炼成的 | 302 |
中级程序员是怎样炼成的 | 214 |
新列表
文章名 | 阅读量 |
---|---|
高级程序员是怎样炼成的 | 584 |
第二次遍历
原文章变为下表,将最多的“初级程序员是怎样炼成的”文章移除
文章名 | 阅读量 |
---|---|
钢铁是怎样炼成的 | 110 |
钻石是怎样炼成的 | 30 |
铜是怎样炼成的 | 60 |
中级程序员是怎样炼成的 | 214 |
新列表
文章名 | 阅读量 |
---|---|
高级程序员是怎样炼成的 | 584 |
初级程序员是怎样炼成的 | 302 |
第三次遍历
原文章变为下表,将最多的“初级程序员是怎样炼成的”文章移除
文章名 | 阅读量 |
---|---|
钢铁是怎样炼成的 | 110 |
钻石是怎样炼成的 | 30 |
铜是怎样炼成的 | 60 |
新列表
文章名 | 阅读量 |
---|---|
高级程序员是怎样炼成的 | 584 |
初级程序员是怎样炼成的 | 302 |
中级程序员是怎样炼成的 | 214 |
多次遍历后
最终得到的新列表
文章名 | 阅读量 |
---|---|
高级程序员是怎样炼成的 | 584 |
初级程序员是怎样炼成的 | 302 |
中级程序员是怎样炼成的 | 214 |
钢铁是怎样炼成的 | 110 |
铜是怎样炼成的 | 60 |
钻石是怎样炼成的 | 30 |
O表示法
要找到阅读数最多的文章,必须检查列表中的每个元素,所以这需要时间为O(n);
这是遍历一次的时间,那么要将列表所有文章排序,需要执行n次,那么就需要的总时间为:
O
(
n
∗
n
)
O(n*n)
O(n∗n),即:
O
(
n
2
)
O(n^2)
O(n2)
这里可能有个疑问,随着排序进行,每次需要检查的元素在减少,最后仅需一次,那么为什么运行时间还是
O
(
n
2
)
O(n^2)
O(n2)?这就涉及到大O表示法中的常数相关了。这里简单说明一下。
通过遍历我们发现规律为 n-1,n-2,n-3······2,1。
平均每场检查元素1/2 * (n+1),因此运行时间为
O
(
n
∗
1
/
2
∗
(
n
+
1
)
)
O(n*1/2*(n+1))
O(n∗1/2∗(n+1))。
但是大O表示法省略1/2这样的常数,因此简写为
O
(
n
2
)
O(n^2)
O(n2)
代码示例
function findSmallest($array){
$smallest = $array[0];
$index = 0;
foreach ($array as $k => $v){
if ($v < $smallest){
$smallest = $v;
$index = $k;
}
}
return $index;
}
function choiceSort($array){
$newArray = [];
foreach ($array as $k => $v){
//找到最小元素位置
$smallest_index = findSmallest($array);
//添加到新列表中
$newArray[] = $array[$smallest_index];
//删除原列表中元素
array_splice($array, $smallest_index, 1);
}
return $newArray;
}
var_dump(choiceSort([11,53,12,6,23,83,2]));
die();