Javascript 冒泡排序的这个实现是错误的吗?
如果我们使用2作为循环,而不是使用通常的do-while循环进行排序,这样可以吗Javascript 冒泡排序的这个实现是错误的吗?,javascript,sorting,bubble-sort,Javascript,Sorting,Bubble Sort,如果我们使用2作为循环,而不是使用通常的do-while循环进行排序,这样可以吗 let bubbleSort = (arr) => { console.log(arr); for(let i=0; i<arr.length; i++) { for (j=0; j<arr.length; j++) { if (arr[j] > arr[j+1]){ console.log("swapp
let bubbleSort = (arr) => {
console.log(arr);
for(let i=0; i<arr.length; i++) {
for (j=0; j<arr.length; j++) {
if (arr[j] > arr[j+1]){
console.log("swapped (i,j)->", arr[j],arr[j+1])
let temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr
}
let bubbleSort=(arr)=>{
控制台日志(arr);
for(设i=0;i所有循环类型do
,而和for
是等价的。它们只是程序员的语法糖,最终在运行时归结为相同的东西
您在这里发布的是一个基本正确的冒泡排序实现,但有几个改进点:
- 错误:代码正在访问内部循环中的越界索引:由于
arr[j+1],因此迭代到j
而不是j
语句。对于越界数组访问,大多数语言都会崩溃或表现出未定义的行为,但JS只是将值与未定义的值进行比较,然后继续
- 潜在错误:内部循环在内部循环中创建了一个全局
j
变量(感谢Kaido指出了这一点)。该变量的值将保持在此函数之外,并可能导致程序中的其他地方出现意外行为。使用let
(或const
,如果不应重新分配变量),以确保它们的作用域位于块的本地
- 在外循环的第一次迭代之后,数组中最右边的元素位于其最终排序位置(因为它是数组中最大的元素)。在外循环的第二次迭代后,数组的最后两个元素处于其最终排序位置。依此类推。因此,我们可以按如下方式缩短内循环的迭代次数:
j
- 如果在任何迭代中没有执行交换,那么我们可以中断——数组已经排序了
这些优化不会提高时间复杂度,正如您所说,时间复杂度为O(n2),但它们值得考虑,因为类似的优化方法可以帮助加快现实世界的排序例程
需要考虑的几个风格点:
- 使用运算符之间的间距(除非它们位于
[]
s中)
- 在交换值时,请考虑使用a以避免使用
temp
变量。正如注释中所指出的,由于每次交换都会产生数组对象创建开销,因此它应该在生产构建中编译出来(尽管冒泡排序在生产中并不合适)
- 与分号和垂直空格一致
这里有一个可能的重写:
const bubbleSort=arr=>{
for(设i=0;iarr[j+1]){
[arr[j],arr[j+1]=[arr[j+1],arr[j]];
交换=真;
}
}
如果(!swapped){break;}
}
返回arr;
};
for(设i=0;i<10000;i++){
常量arr=Array(100.fill().map(e=>~~(Math.random()*30));
const expected=JSON.stringify(arr.slice().sort((a,b)=>a-b));
const-actual=JSON.stringify(bubbleSort(arr.slice());
如果(实际!==预期){
抛出新错误(`test failed:expected${expected}但得到${actual}`);
}
}
console.log(“10000个测试通过”);
将“arr[arr.length-1]”与“arr[arr.length]”进行比较时,是否会出现错误?此版本缺少冒泡排序的一个重要功能-在上次扫描未进行交换时停止。您是否要求我们为您做功课?进行冒泡排序的唯一原因是学术理解,在生产应用程序中使用冒泡排序是违反直觉的。@Adrianbra,而且并非所有代码问题都需要与生产代码有关。We欢迎纯粹的学术和教育问题。家庭作业是,但在这种情况下做出这样的假设似乎是冒昧的。不,这不是为了学术目的,我自己在学习泡泡排序,阅读理论并尝试实施,希望得到关于我做错了什么的反馈。谢谢你的回答!你所有的观点都非常有用l!!。我有一个关于你在内部循环上的点的问题…循环是如何越界的?我的意思是“j”已经在j=0上迭代到小于arr.length。我在这里缺少一个点吗?对不起,我找到了点。函数正在访问arr[j+1]元素!我们可以对sort和bubbleSort进行速度比较吗?(可能是控制台时间?)我可以补充一点,但我认为OP明白冒泡排序是非常无用的,而且可以说,Array#sort
将给冒泡排序带来可怕的打击。哇,不要在这里使用解构关联。是的,它可能会使代码更可读,但您正在编写排序算法,每个su创建两个新数组b-迭代是一个非常糟糕的主意,垃圾收集器会不断启动。仅供参考,在我的FF上使用一个temp变量,我得到了大约400毫秒的时间来完全执行代码段,而在分解结构时则是2500毫秒。