JavaScript中冒泡排序,同样的写法,为什么封装在函数中会出现死循环,而没有封装的不会出现。

下面两端代码:
1.函数封装的冒泡排序

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<title></title>

<link rel="stylesheet" href="">

<script type="text/javascript">

var arr1 = sort([2,3,4,9,7]);

function sort(arr) {

for (var i = 0; i < arr.length - 1; i++) {

for (var j = 0; j < arr.length - i - 1; j++) {

if (arr[j] > arr[j + 1]) {}

var temp = arr[j];

arr[j] = arr[j + 1];

arr[j + 1] = temp;

}

}

return arr;

}

console.log(arr1);

</script>

</head>

<body>

</body>

</html>

这段代码执行是没有问题的。

2.没有封装成函数的冒泡排序

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<title></title>

<link rel="stylesheet" href="">

<script type="text/javascript">

var arr = [2,3,4,9,7];

for (var i = 0; i <= arr.length - 1; i++) {

for (var j = 0; j <= arr.length - i - 1; j++) {

if (arr[j] > arr[j + 1]) {

var temp = arr[j];

arr[j] = arr[j + 1];

arr[j+ 1] = temp;

}

}

}

console.log(arr);

</script>

</head>

<body>

</body>

</html>

这段代码运行也没有问题。

注:两端代码的循环条件有区别。(j <arr.length 和 j <= arr.length)

问题来了

我在下面的代码中会出现死循环,为什么我在2中的代码不会出现死循环?(我把函数中的循环 j < arr.length改为了 j <= arr.length)

注:已经知道为什么出现死循环,就是想知道同样的写法,为什么没有封装的不会出现死循环。

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<title></title>

<link rel="stylesheet" href="">

<script type="text/javascript">

var arr1 = sort([2,3,4,9,7]);

function sort(arr) {

for (var i = 0; i <= arr.length - 1; i++) {

for (var j = 0; j <= arr.length - i - 1; j++) {

if (arr[j] > arr[j + 1]) {}

var temp = arr[j];

arr[j] = arr[j + 1];

arr[j + 1] = temp;

}

}

return arr;

}

console.log(arr1);

</script>

</head>

<body>

</body>

</html>

回答

        var arr1 = sort([2,3,4,9,7]);

function sort(arr) {

for (var i = 0; i <= arr.length - 1; i++) {

for (var j = 0; j <= arr.length - i - 1; j++) {

if (arr[j] > arr[j + 1]) {}

var temp = arr[j];

arr[j] = arr[j + 1];

arr[j + 1] = temp;

}

}

return arr;

}

有等号,j 就可以等于arr.length - 1(当 i==0 的时候)。此时,arr[j+1] 不在数组范围内,已经越界了。其值应该是 undefined

undefined 做比较,一定是 false 。这样你的 2 里的交换不会执行。但是 1 跟 3 的交换是这样的:

                    if (arr[j] > arr[j + 1]) {}

// ^ 这是为什么 ....

它实际不受 if 控制(这是错的,改改吧 ... )。

于是 arr[j+1]=temp 一定会执行,执行以后,数组变长了。

于是内层循环每执行一次数值长度增加一,j 也每此增加一,于是 j <= arr.length - i -i 总是是 true

  var arr = sort([2, 3, 4, 9, 7]);

function sort(arr) {

for (var i = 0; i <= arr.length - 1; i++) {

console.log(i,'哈哈哈哈哈哈');

for (var j = 0; j <= arr.length - i - 1; j++) {

console.log( arr.length ,'jjjjjjjj');

if (arr[j] > arr[j + 1]) {

var temp = arr[j];

arr[j] = arr[j + 1];

arr[j + 1] = temp;

}

}

}

return arr;

}

console.log(arr);

if (arr[j] > arr[j + 1]) {},写外面造成内部for死循环,因为arr的长度一直在增加

很关键的一点,JS数组越界赋值会自动给数组扩容。

let arr = [1]

arr[5] = 1

console.log(arr.length) // 输出6

上述3段代码中后2段都存在越界访问(访问不会扩容,不同于赋值),但二段和三段内层循环的if语句不相同。三段的内层循环最后一次遍历都会导致越界赋值(if没用),而二段则不会,因为任意数字和越界访问的undefined比较都返回false,if条件不成立。

以上是 JavaScript中冒泡排序,同样的写法,为什么封装在函数中会出现死循环,而没有封装的不会出现。 的全部内容, 来源链接: utcz.com/a/38384.html

回到顶部