Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript合并排序和递归_Javascript_Arrays_Sorting_Recursion_Mergesort - Fatal编程技术网

javascript合并排序和递归

javascript合并排序和递归,javascript,arrays,sorting,recursion,mergesort,Javascript,Arrays,Sorting,Recursion,Mergesort,我试图理解JavaScript合并排序函数是如何工作的。我很难理解递归函数是如何工作的。代码如下: const mergeSort = array => { if (array.length < 2) { //function stop here return array } const middle = Math.floor(array.length / 2); const leftSide = array.slice(0, middle);

我试图理解JavaScript合并排序函数是如何工作的。我很难理解递归函数是如何工作的。代码如下:

const mergeSort = array => {
  if (array.length < 2) {
    //function stop here
    return array
  }

  const middle = Math.floor(array.length / 2);
  const leftSide = array.slice(0, middle);
  const rightSide = array.slice(middle, array.length);
  return merge(mergeSort(leftSide), mergeSort(rightSide))

};

const merge = (left, right) => {
  const result = [];

  while (left.length && right.length) {
    if (left[0] <= right[0]) {
      result.push(left.shift());
    } else {
      result.push(right.shift);
    }
  }

  while(left.length) result.push(left.shift());

  while(right.length) result.push(right.shift());

  return result;
}
mergeSort([5,3,8,10,4,1])
const mergeSort=array=>{
if(array.length<2){
//函数停止在这里
返回数组
}
const middle=数学楼层(array.length/2);
const leftSide=array.slice(0,中间);
const rightSide=array.slice(中间,array.length);
返回合并(合并排序(左侧),合并排序(右侧))
};
常量合并=(左、右)=>{
常量结果=[];
while(left.length&&right.length){

如果(左[0]要理解递归,可以使用缩进跟踪所有递归级别。例如:

const mergeSort = (array, level) => {
  logWithLevel(level, "Start sort array " + array);
  if(array.length < 2) {
    //function stop here
    logWithLevel(level, "Finish sort array " + array);
    return array;
  }

  const middle = Math.floor(array.length / 2);
  logWithLevel(level, "middle element is " + array[middle])
  const leftSide = array.slice(0, middle);
  const rightSide = array.slice(middle, array.length);
  var result = merge(mergeSort(leftSide, level + 1), mergeSort(rightSide, level + 1));
  logWithLevel(level, "Finish sort array " + result);
  return result;
};

const merge = (left, right) => {
  const result = [];

  while(left.length && right.length){
    if(left[0] <= right[0]){
      result.push(left.shift());
    }else{
      result.push(right.shift());
    }
  }

  while(left.length) result.push(left.shift());

  while(right.length) result.push(right.shift());

  return result;
}

const logWithLevel = (level, data) => {
    var s = ""
    for (i = 0; i < level; i++) {
        s += "    ";
    }
    console.log(s + data);
}

合并排序的工作原理是分而治之。在这里,一个问题被分解成一个较小的子问题,并一直持续到问题可解为止。然后我们通过合并较小的已解问题来解决较大的问题

在合并排序中,我们将数组分成更小的数组,直到它的大小为1,并且大小为1的数组已经被排序。在此之后,我们合并更小的数组,这样新创建的数组也会被排序

在图中,您可以看到在第四级中,所有子阵列的大小都为1,从那里开始,我们将合并子阵列

图像来源:

函数合并排序(输入){
const{length:arraySize}=输入;
if(arraySize<2)返回输入;
const mid=数学楼层(阵列化/2);
const sortedLeftArray=mergeSort(input.slice(0,mid));
const sortedRightArray=mergeSort(input.slice(mid,arraySize));
返回合并(sortedLeftArray、SORTDRIGHTARRAY);
}
函数合并(左、右){
让结果=[]
while(left.length&&right.length){
if(左[0]<右[0]){
结果.推(left.shift())
}否则{
result.push(right.shift())
}
}
/*左/右数组将为空或同时为空*/
返回[…结果,…左,…右];
}
console.log(合并排序([5,3,8,10,4,1]))
函数排序(arr){
常量staticArr=[…arr]
函数recMaxSort(arrayARG,maxEL=0,resultar=[]){
常数[firstEl,…rest]=arrayARG;
if(staticArr.length==resultArr.length){
返回结果器
}
如果(!firstEl){
resultar=[maxEL,…resultar]
const newArray=staticArr.filter(el=>{return!resultArr.includes(el)})
返回recMaxSort(newArray,0,resultar)
}
如果(最大值>第一值){
返回recMaxSort(rest、maxEL、resultArr)
}else if(firstEl>=maxEL){
返回recMaxSort(rest、firstEl、resultArr)
}
}
返回recMaxSort(arr)
}

console.log(sort([231,4,7,3,54500]);
注意,所有值要么是当前函数调用的本地值,要么是传递给它的参数。因此,在对
[5]
[3,8]
进行排序后,
返回merge…
行调用
[5]
[3,8]
,后者返回
[3,5,8]
。类似的情况发生在右半部分:
[10]
被返回,
[4,1]
被排序为
[1,4]
,然后
[10]
[1,4]
被合并为
[1,4,10]
。最后
[3,5,8]
[1,4,10]
被合并为
[1,3,4,5,8,10]
。每次递归调用都会保留自己的局部变量副本。请在纸上写下这一点:从
[5,3,8,10,4,1]
开始,将其拆分为
mergeSort
两个数组。这两个数组都(递归地)再次传递到
mergeSort
,其中
[5,3,8]
变成
[5]
[3,8]
。对于
[5]
我们完成了,它按原样返回。对于
[3,8]
,我们再次递归,它们最终返回为
[3]
[8]
.get
merge
d:在合并步骤中会发生什么?写出来:如果你想了解任何算法,这是一个重要的练习。但是merge首先像merge(3,8)那样被调用,然后执行,但函数本身不能保留这些值,然后它用5再次执行,但我不明白5是如何传递的它不能被合并([3,8,5])因为mergeSort只返回一个值…嘿,Mike,merge函数内的拆分hapening或merge是否只使用一个参数调用?@shaunaa-merge使用两个参数调用,每个参数都是一个数组,merge返回一个合并数组。这是一种非常低效的实现合并排序的方法。这会更好er对第二个数组进行一次性分配,然后在两个数组之间来回合并,将数组和索引作为参数传递。OP正在寻找代码的解释,而不是没有解释的更多代码…虽然此代码可能会解决问题,但一个好的答案应该解释代码的作用以及它如何帮助您添加一些解释?@dan1st您好!您到底不明白什么?我的函数基于数组分解。当递归进行时,比较数组中的所有值。我之所以这样写是因为我在LQP审阅队列中得到了您的答案,而您只是编写了代码,没有解释它。
> mergeSort([5,3,8,10,4,1], 0)
    Start sort array 5,3,8,10,4,1
    middle element is 10
        Start sort array 5,3,8
        middle element is 3
            Start sort array 5
            Finish sort array 5
            Start sort array 3,8
            middle element is 8
                Start sort array 3
                Finish sort array 3
                Start sort array 8
                Finish sort array 8
            Finish sort array 3,8
        Finish sort array 3,5,8
        Start sort array 10,4,1
        middle element is 4
            Start sort array 10
            Finish sort array 10
            Start sort array 4,1
            middle element is 1
                Start sort array 4
                Finish sort array 4
                Start sort array 1
                Finish sort array 1
            Finish sort array 1,4
        Finish sort array 1,4,10
    Finish sort array 1,3,4,5,8,10
Sorting with recursive