You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS冒泡排序可视化:如何在循环中获取正确的数组快照?

冒泡排序可视化:数组状态存储问题分析与解决

嘿,我来帮你理清楚这个问题的根源,以及怎么解决它~

为什么newArray里全是最终排序后的数组?

核心原因是JavaScript中的数组是引用类型:你执行newArray.push(arr)的时候,并没有把当前arr的元素复制一份存进去,而是把arr这个数组的内存引用添加到了newArray里。

之后你每次在排序过程中修改arr的元素,所有指向这个引用的位置(也就是newArray里的每一项)都会同步变化。等到排序完成,newArray里的所有元素其实都是同一个数组的引用,自然显示的都是最终排好序的结果。

怎么保存每次交换后的正确数组状态?

解决方法很简单:每次要保存数组状态时,创建当前arr的副本,再把副本push到newArray里。常用的创建数组副本的方法有两种:

  • 使用arr.slice():这是数组的原生方法,调用后会返回一个包含原数组所有元素的新数组
  • 使用扩展运算符[...arr]:这是ES6+的语法,同样能快速生成原数组的浅拷贝副本

修改后的完整代码

var arr = [1, 5, 3, 7, 2];
var newArray = [];

for (var i = 0; i < arr.length - 1; i++) {
  for (var j = 0; j < arr.length - 1 - i; j++) {
    if (arr[j] > arr[j + 1]) {
      // 你的交换逻辑是没问题的,不用改
      arr[j] = arr[j] + arr[j + 1];
      arr[j + 1] = arr[j] - arr[j + 1];
      arr[j] = arr[j] - arr[j + 1];
      
      // 关键:创建数组副本再push
      newArray.push([...arr]); 
      // 或者用 slice() 写法:newArray.push(arr.slice());
      console.log(arr);
    }
  }
}

// 现在打印newArray就能看到每次交换后的不同状态了
console.log(newArray);

进阶:记录完整排序轮次(可选)

如果你的可视化需要展示每一轮排序后的状态(即使某一轮没有发生交换),可以把保存状态的逻辑放到内层循环外面,同时加上交换标记提前终止排序,这样能更完整地展示排序全过程:

var arr = [1, 5, 3, 7, 2];
var newArray = [];

// 先保存初始状态
newArray.push([...arr]);

for (var i = 0; i < arr.length - 1; i++) {
  var hasSwapped = false; // 标记本轮是否有元素交换
  for (var j = 0; j < arr.length - 1 - i; j++) {
    if (arr[j] > arr[j + 1]) {
      // 交换元素
      arr[j] = arr[j] + arr[j + 1];
      arr[j + 1] = arr[j] - arr[j + 1];
      arr[j] = arr[j] - arr[j + 1];
      hasSwapped = true;
    }
  }
  // 保存本轮结束后的数组状态
  newArray.push([...arr]);
  // 如果本轮没有交换,说明数组已经有序,提前退出循环
  if (!hasSwapped) break;
}

console.log(newArray);

这样newArray里就包含了从初始数组到每一轮排序后的所有状态,完全满足可视化的需求啦~

内容的提问来源于stack exchange,提问作者Z.jazz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:10:30