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

如何不使用push等原生函数实现数组排序移零至末尾并合并方法?

问题描述

给定数组:

const myArray = [1, 543, 0, 232, 1, 45654, -5, 0, 7, 4, 0, 43, 77, 0, 77, 0]

需要完成两个操作:

  1. 将数组按升序排列
  2. 将所有0移至数组末尾
    预期输出:
[-5, 1, 1, 4, 7, 43, 77, 77, 232, 543, 45654, 0, 0, 0, 0, 0]

目前已实现排序功能的代码:

function sorting(arr) {
  for(let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr.length - i -1; j++) {
      if(arr[j+1] < arr[j]) {
        [arr[j+1], arr[j]] = [arr[j], arr[j+1]];
      }
    }
  }
  return arr;
}

移零功能使用了push原生函数,实现代码如下:

function moveZeros(arr) {
  let newArray = [];
  let counter = 0;
  for (let i = 0; i < arr.length; i++) {
    if(arr[i] !== 0) {
      newArray.push(arr[i]);
    } else { 
      counter++; 
    }
  }
  for (let j = 0; j < counter; j++) {
    newArray.push(0);
  }
  return newArray;
}

现在有两个疑问:

  • 是否存在不使用push等原生函数的移零实现方法?
  • 如何将排序与移零方法合并为一个函数?

解决方案

一、不使用push的移零实现

可以用索引直接赋值的方式实现,完全不需要依赖push:

function moveZerosWithoutPush(arr) {
  const newArray = new Array(arr.length); // 提前创建和原数组长度一致的空数组
  let nonZeroIndex = 0;
  let zeroCount = 0;

  // 先把非零元素按顺序放到新数组前面
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] !== 0) {
      newArray[nonZeroIndex] = arr[i];
      nonZeroIndex++;
    } else {
      zeroCount++;
    }
  }

  // 剩下的位置全部填0
  for (let i = arr.length - zeroCount; i < arr.length; i++) {
    newArray[i] = 0;
  }

  return newArray;
}

思路很简单:先定好新数组的长度,用变量记录非零元素该放的位置,填完非零元素后,在数组末尾的对应位置直接赋值0就行。

二、合并排序与移零为单个函数

有两种实现方式,一种是整合现有逻辑,另一种是优化排序规则一步到位:

方式1:整合现有排序和移零逻辑

直接把排序和移零的步骤放到同一个函数里,用不依赖push的移零方法:

function sortAndMoveZeros(arr) {
  // 第一步:冒泡排序(先复制原数组,避免修改原数据)
  const sortedArr = [...arr];
  for(let i = 0; i < sortedArr.length; i++) {
    for (let j = 0; j < sortedArr.length - i -1; j++) {
      if(sortedArr[j+1] < sortedArr[j]) {
        [sortedArr[j+1], sortedArr[j]] = [sortedArr[j], sortedArr[j+1]];
      }
    }
  }

  // 第二步:不使用push的移零操作
  const result = new Array(sortedArr.length);
  let nonZeroIdx = 0;
  let zeroCount = 0;

  for (let i = 0; i < sortedArr.length; i++) {
    if (sortedArr[i] !== 0) {
      result[nonZeroIdx] = sortedArr[i];
      nonZeroIdx++;
    } else {
      zeroCount++;
    }
  }

  for (let i = sortedArr.length - zeroCount; i < sortedArr.length; i++) {
    result[i] = 0;
  }

  return result;
}

方式2:优化排序规则,一步完成排序+移零

可以直接修改冒泡排序的交换条件,让排序过程同时完成移零,效率更高:

function sortAndMoveZerosOptimized(arr) {
  const arrCopy = [...arr];
  const len = arrCopy.length;

  for (let i = 0; i < len; i++) {
    for (let j = 0; j < len - i - 1; j++) {
      // 交换规则:要么当前元素是0,要么当前元素大于下一个非零元素,就交换
      const shouldSwap = (arrCopy[j] === 0) || 
                        (arrCopy[j] > arrCopy[j+1] && arrCopy[j+1] !== 0);
      
      if (shouldSwap) {
        [arrCopy[j], arrCopy[j+1]] = [arrCopy[j+1], arrCopy[j]];
      }
    }
  }

  return arrCopy;
}

这个方法的核心是调整冒泡排序的判断逻辑:遇到0就优先和后面的非零元素交换,同时正常给非零元素做升序排序。这样一轮排序完成后,所有0都会被“挤”到数组末尾,非零元素也刚好是升序排列,一步到位。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:40:29