[英]js Bubble sort not processing all elements correctly
I pass in elements array [5,4,3]. 我传入元素数组[5,4,3]。 The bubble sort manages to push 5 the end, this is fine, but when it loops through a third time to locate the second to last element, the loop breaks and the incorrect ordered array is returned... not sure why, cheers guys
冒泡排序设法将5推到最后,这很好,但是当它第三次循环以查找倒数第二个元素时,循环中断并且返回了不正确的有序数组...不知道为什么,干杯
this.bubbleSort = function (elements) {
//Loop through to the second to last index. By the time we get to the last index, its already //been compared with what’s in front of it
var hasHadChange;
for (var x = 0; x < elements.length - 1; x++) {
hasHadChange = false;
//Loop through to the second to last index.
for (var y = 0; y < elements.length - 1; y++) {
//Check the current item(x) in the array plus the item next to current item (x+1), if its larger
if (elements[y] > elements[y + 1]) {
//Acknowledge there has been a change
hasHadChange = true;
//Swap the items around
var temp = elements[y];
elements[y] = elements[y + 1];
elements[y + 1] = temp;
//This continues until the largest value has bubbled to the right
}
}
}
return elements;
}
You need to use separate variables for the inner and the outer loop. 您需要为内部和外部循环使用单独的变量。 When you exit the inner loop,
x
will be equal to the length, so the outer loop will end also. 退出内循环时,
x
等于长度,因此外循环也将结束。
You should use separate variables in inner and outer loops. 您应该在内外循环中使用单独的变量。 Using
y
in inner loop instead will give you the correct answer. 在内部循环中使用
y
可以为您提供正确的答案。
var bubbleSort = function (elements) {
//Loop through to the second to last index. By the time we get to the last index, its already //been compared with what’s in front of it
var hasHadChange;
for (var x = 0; x < elements.length - 1; x++) {
hasHadChange = false;
//Loop through to the second to last index.
for (y = 0; y < elements.length - 1; y++) {
//Check the current item(x) in the array plus the item next to current item (x+1), if its larger
if (elements[y] > elements[y + 1]) {
//Acknowledge there has been a change
hasHadChange = true;
//Swap the items around
var temp = elements[y];
elements[y] = elements[y + 1];
elements[y + 1] = temp;
//This continues until the largest value has bubbled to the right
}
}
}
return elements;
}
The reason behind this is variable hoisting . 其背后的原因是可变吊装 。
When a variable is declared, it breaks into two parts. 声明变量后,它分为两部分。 One part moves to top of it's scope, other stays at it's position.
一部分移至其作用域的顶部,另一部分则保持在其位置。 For Example,
例如,
function foo() {
if (false) {
var x = 1;
}
var y = 1;
}
Will look like : 看起来像:
function foo() {
var x = undefined; //Declaration of x is hoisted
var y = undefined; //Declaration of y is hoisted
if (false) {
x = 1; //Assignment still occurs where we intended
}
y = 1; //Assignment still occurs where we intended
}
This is what happened in the code. 这就是代码中发生的事情。 Using same variable in both loops makes them overwrite each other values.
在两个循环中使用相同的变量会使它们彼此覆盖值。 Hence the result.
因此,结果。
From ECMAScript standard 5.1 : 从ECMAScript标准5.1开始 :
A variable statement declares variables that are created as defined in 10.5.
变量语句声明按10.5定义创建的变量。 Variables are initialised to undefined when created.
变量在创建时初始化为未定义。 A variable with an Initialiser is assigned the value of its AssignmentExpression when the VariableStatement is executed, not when the variable is created.
在执行VariableStatement时(而不是在创建变量时),将为带有Initialiser的变量分配其AssignmentExpression的值。
See this MDN doc for more details. 见这 MDN文档了解更多详情。 Look for topic var hoisting.
寻找主题var提升。
Update 更新
Using let
which has block level scope, you can have variable x
in both loops. 使用具有块级作用域的
let
,您可以在两个循环中都有变量x
。
var bubbleSort = function (elements) {
//Loop through to the second to last index. By the time we get to the last index, its already //been compared with what’s in front of it
var hasHadChange;
for (var x = 0; x < elements.length - 1; x++) {
hasHadChange = false;
//Loop through to the second to last index.
for (let x = 0; x < elements.length - 1; x++) {
//Check the current item(x) in the array plus the item next to current item (x+1), if its larger
if (elements[x] > elements[x + 1]) {
//Acknowledge there has been a change
hasHadChange = true;
//Swap the items around
var temp = elements[x];
elements[x] = elements[x + 1];
elements[x + 1] = temp;
//This continues until the largest value has bubbled to the right
}
}
}
return elements;
}
您在两个for循环中使用相同的控制变量x
,例如应使用x
和y
类的变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.