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

排序可视化工具中归并排序函数触发调用栈溢出错误的问题求助

解决归并排序递归栈溢出及功能异常问题

我一眼就看到几个导致栈溢出和功能异常的问题,咱们一步步来解决:

1. 全局变量+递归参数不匹配导致无限递归

你定义的mergeSort()函数没有参数,但递归调用时却传了mergeSort(el, low, mid)这类参数,同时还依赖全局的low和high变量。这会导致每次递归进入mergeSort时,始终使用全局的初始low=0和high=el.length-1,永远满足不了if (low >= high)的终止条件,进而无限递归,触发栈溢出。

修复方案:
把mergeSort改成带参数的函数,移除全局的low和high,在点击事件里传入初始边界值:

document.querySelector(".merge").addEventListener("click", function() {
  const bars = document.querySelectorAll(".bar");
  mergeSort(bars, 0, bars.length - 1);
});

// 带参数的mergeSort
function mergeSort(arr, low, high){
 if (low >= high){
 return;
 }
 var mid = parseInt((low + high)/2);
 mergeSort(arr, low, mid);
 mergeSort(arr, mid + 1, high);
 merge(arr, low, mid, high);
}

2. offsetHeight是只读属性,无法直接赋值

你在merge函数里尝试直接修改arr[k].offsetHeight,但offsetHeight是元素的只读属性,仅用于获取当前渲染后的高度,不能直接设置。要修改元素高度,应该用style.height属性,并且要带上单位(比如px)。

修复方案:
先把高度值转成数字进行比较,再通过style.height设置:

function merge(arr, low, mid, high){
 var n = mid - low + 1;
 var m = high - mid;
 var leftArray = new Array(n);
 var rightArray = new Array(m);
 
 // 存储元素的高度数值(兼容style.height和offsetHeight)
 for(var i = 0; i < n; i++){
 leftArray[i] = parseInt(arr[low + i].style.height) || arr[low + i].offsetHeight;
 }
 for(var j = 0; j < m; j++){
 rightArray[j] = parseInt(arr[mid + 1 + j].style.height) || arr[mid + 1 + j].offsetHeight;
 }
 
 var i = 0;
 var j = 0;
 var k = low;
 while (i < n && j < m){
 if (leftArray[i] <= rightArray[j]){
 arr[k].style.height = `${leftArray[i]}px`;
 i++;
 }else{
 arr[k].style.height = `${rightArray[j]}px`;
 j++;
 }
 k++;
 }
 while (i < n){
 arr[k].style.height = `${leftArray[i]}px`;
 i++;
 k++;
 }
 while (j < m){
 arr[k].style.height = `${rightArray[j]}px`;
 j++;
 }
}

3. 额外优化:避免过时的DOM引用

原来的代码里var el = document.querySelectorAll(".bar");是全局的,多次点击可能会引用过时的DOM元素。把它放到点击事件回调里,每次点击都获取最新的元素集合,确保操作的是当前页面的元素。

修复后的完整代码

document.querySelector(".merge").addEventListener("click", function() {
  const bars = document.querySelectorAll(".bar");
  mergeSort(bars, 0, bars.length - 1);
});

function mergeSort(arr, low, high){
 if (low >= high){
 return;
 }
 const mid = Math.floor((low + high) / 2); // 用Math.floor比parseInt更稳妥
 mergeSort(arr, low, mid);
 mergeSort(arr, mid + 1, high);
 merge(arr, low, mid, high);
}

function merge(arr, low, mid, high){
 const n = mid - low + 1;
 const m = high - mid;
 const leftArray = [];
 const rightArray = [];
 
 // 收集左右数组的高度数值
 for(let i = 0; i < n; i++){
   const bar = arr[low + i];
   leftArray.push(parseInt(bar.style.height) || bar.offsetHeight);
 }
 for(let j = 0; j < m; j++){
   const bar = arr[mid + 1 + j];
   rightArray.push(parseInt(bar.style.height) || bar.offsetHeight);
 }
 
 let i = 0, j = 0, k = low;
 while (i < n && j < m){
 if (leftArray[i] <= rightArray[j]){
 arr[k].style.height = `${leftArray[i]}px`;
 i++;
 }else{
 arr[k].style.height = `${rightArray[j]}px`;
 j++;
 }
 k++;
 }
 while (i < n){
 arr[k].style.height = `${leftArray[i]}px`;
 i++;
 k++;
 }
 while (j < m){
 arr[k].style.height = `${rightArray[j]}px`;
 j++;
 k++;
 }
}

这样修改后,递归的终止条件能正常触发,不会再出现栈溢出,同时也能正确修改元素高度实现排序可视化了。

内容的提问来源于stack exchange,提问作者Bayeroabdul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:44:57