哪种排序技术更快:泡泡或选择排序,为什么?两者都同样有效吗?
答案 0 :(得分:12)
Wikipedia说(强调补充):
简单平均情况Θ(n 2 ) 算法,几乎选择排序 总是优于冒泡排序和 gnome排序,但一般 优于插入排序。 插入排序非常相似 在第k次迭代之后,第一个k 数组中的元素已排序 订购。插入排序的优点是 它只扫描尽可能多的元素 它需要为了放置k + 1st 元素,而选择排序必须 扫描所有剩余的元素以查找 第k + 1个元素。
简单的计算表明 因此通常会插入排序 执行大约一半的比较 作为选择排序,虽然它可以 表现同样多或少得多 取决于阵列的顺序 在排序之前。它可以被视为 一些实时的优势 选择排序的应用程序 无论如何都表现相同 插入时的数组顺序 sort的运行时间可能会有所不同 相当。但是,这更多 通常是插入排序的一个优点 因为它运行得更有效率 如果数组已经排序或 “接近排序。”
虽然选择排序比较好 插入排序的数量 写(Θ(n)互换与Ο(n 2 ) 交换),它几乎总是远远超过 (并且从不打败)写入次数 循环排序作为循环排序 理论上在数量上是最优的 写作如果这很重要 写得更多 比阅读昂贵,比如 EEPROM或闪存,每一个 写减少了生命周期 存储器中。
最后,选择排序很重要 在较大的阵列上优于Θ(n log n)分而治之的算法 例如mergesort。但是,插入 排序或选择排序都是 对于小型阵列通常更快 (即少于10-20个元素)。一个 在实践中有用的优化 切换算法就是切换 插入排序或选择排序 对于“足够小”的子列表。
而且,维基百科bubble sort(重点补充):
冒泡排序有最坏情况和平均值 复杂性О(n 2 ),其中n是 被分类的项目数量。那里 存在许多排序算法 最糟糕的情况或 O(n log n)的平均复杂度。甚至 其他О(n 2 )排序算法,例如 作为插入排序,往往更好 性能比冒泡排序。 因此,冒泡排序不是一个 n是时的实用排序算法 大。强>
唯一显着的优势 冒泡排序超过了其他大多数 实现,甚至快速排序,但是 不插入排序,就是那个 检测列表的能力 排序有效地构建到 算法。泡泡排序的表现 在已经排序的列表上 (最好的情况)是O(n)。相比之下,大多数 其他算法,甚至那些算法 更好的平均案例复杂性, 执行他们的整个排序过程 在集合上,因此更复杂。 但是,不仅插入排序 也有这个机制,但它也 在列表上表现更好 基本上排序(有一个小的 反转次数)。
答案 1 :(得分:5)
与冒泡排序相比,选择排序执行的交换数量较少;因此,即使两种排序方法都是O(N 2 ),选择排序也会更快,更有效!
答案 2 :(得分:1)
冒泡排序算法被认为是最简单和最低效的算法,但与冒泡排序相比,选择排序算法是有效的。冒泡排序还会占用额外的空间来存储临时变量,并且需要更多的交换。
答案 3 :(得分:1)
在比较这两种算法时,我们必须考虑这些算法中发生的两种操作 i)比较 ii)交换 在比较运算的基础上,两者的效率均相同 但是如果您考虑交换操作,您会发现选择排序更为有效 考虑大小为100的降序数组,我们必须按升序对其进行排序 在此问题中,气泡排序将进行100 * 100 =(10000)个apprx交换操作,而在 SELCTION SORT 情况下,将仅进行100个交换操作,因为每个操作都进行选择排序迭代只有一次交换
答案 4 :(得分:0)
即使它们都具有可比较的,差的,最差的和平均的案例复杂性,但有certain points表明选择排序优于冒泡排序。
选择排序花费大部分时间 时间试图找到最低限度 元素在“未分类”的部分 阵列。它清楚地显示了相似性 在选择排序和泡沫之间 分类。冒泡排序“选择”了 每个最大剩余元素 阶段,但浪费了一些努力 传递一些命令“未分类” 阵列的一部分。
答案 5 :(得分:0)
尽管Senthil的link朝着正确的方向前进,但我似乎在这里或其他地方都找不到令人满意的解决方案。
这个问题最初让我感到困惑,因为可以通过在子数组(或链表等)通过后执行值交换失败来尽早终止外循环来优化冒泡排序。选择排序无法以这种方式提供帮助,那么为什么它会跑赢大市?两者在通用性上都很弱-O(n ^ 2)-那么为什么至少可以稍微改善一下呢?
答案完全基于对我自己和其他实现的检查,是气泡排序对每个单比较命中都会进行值交换(读,写,写)。选择排序仅记录新的边界值(最小值用于升序排序,最大值用于降序排序),然后在遍历结束时将其替换掉。
void swapInt(int *ptr1, int *ptr2) {
int temp;
temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}
/* compare and swap over a shrinking sub-array */
void bubbleSortArray(int a[], const int aSize) {
int unsorted, i, iMax = (aSize - 1);
do {
unsorted = 0;
for (i = 0; i < iMax; i++) {
if ( a[i] > a[i + 1] ) {
unsorted = 1;
/* swap every time comparison is true */
swapInt(&a[i], &a[i + 1]);
}
}
--iMax;
} while (unsorted);
}
/* compare to find min value, write it before shrinking the sub-array */
void selectSortArray(int a[], const int aSize) {
int i, j, mindex;
for (i = 0; i < (aSize - 1); i++) {
mindex = i;
for (j = (i + 1); j < aSize; j++) {
if ( a[j] < a[mindex] ) mindex = j;
}
/* swap after inner loop terminates */
swapInt(&a[i], &a[mindex]);
}
}
答案 6 :(得分:0)
气泡排序使用更多的交换时间,而选择排序避免了这种情况。
使用选择排序时,它最多交换n次。但是当使用冒泡排序时,它几乎交换n *(n-1)。显然,即使在内存中,读取时间也比写入时间短。比较时间和其他运行时间可以忽略。因此,交换时间是问题的关键瓶颈。
答案 7 :(得分:0)
在冒泡排序中,我们有更多的比较和交换。
在一个包含 10 个元素的数组中,我们在第一遍中有 9 次比较,在第二遍 7,6 中有 8 次比较,依此类推。在每 8 或 9 次比较中,我们只能交换元素。
在选择排序中,我们首先找到所有元素中的最小元素并将其放置在元素的 0 索引处。
两种算法的复杂度都是 O(n2),但在最坏的情况下,冒泡排序的复杂度为 O(n2),选择的复杂度为 O(n2),最好的情况下,冒泡排序的复杂度为 O(n) 和选择排序有 O(n2)