Javascript 数组上JS二进制搜索的递归与非递归

Javascript 数组上JS二进制搜索的递归与非递归,javascript,arrays,recursion,binary-search,Javascript,Arrays,Recursion,Binary Search,我编写了一个递归方法,用于在数组中查找不重复的单个项(而所有其他项都成对且相邻)。我的问题是,在没有递归的情况下(可能使用while循环)能做到这一点吗?在函数中使用循环是否比仅使用递归更有效(在内存方面) 当前解决方案: function findSingularElement(arr, low, high) { // base cases if (arr.length < 3) return console.log('Invalid length of array.');

我编写了一个递归方法,用于在数组中查找不重复的单个项(而所有其他项都成对且相邻)。我的问题是,在没有递归的情况下(可能使用while循环)能做到这一点吗?在函数中使用循环是否比仅使用递归更有效(在内存方面)

当前解决方案:

function findSingularElement(arr, low, high) {
  // base cases
  if (arr.length < 3) return console.log('Invalid length of array.');
  if (low > high) return;
  if (low == high) return console.log(arr[low]);

  var mid = low + (high - low) / 2;

  if (mid % 2 === 0) {
    if (arr[mid] == arr[mid + 1]) {
      return findSingularElement(arr, mid + 2, high);
    } else {
      return findSingularElement(arr, low, mid);
    }
  } else {
    if (arr[mid] == arr[mid - 1]) {
      return findSingularElement(arr, mid + 1, high);
    } else {
      return findSingularElement(arr, low, mid - 1);
    }
  }
}

var array = [1, 1, 3, 3, 4, 5, 5, 7, 7, 8, 8];
函数查找奇异元素(arr、低、高){
//基本情况
if(arr.length<3)返回console.log(“数组长度无效”);
如果(低>高)返回;
if(低==高)返回console.log(arr[low]);
var中=低+(高-低)/2;
如果(中间%2==0){
如果(arr[mid]==arr[mid+1]){
返回findSingularElement(arr,中+2,高);
}否则{
返回findSingularElement(arr、low、mid);
}
}否则{
如果(arr[mid]==arr[mid-1]){
返回findSingularElement(arr,中+1,高);
}否则{
返回findSingularElement(arr、low、mid-1);
}
}
}
var数组=[1,1,3,3,4,5,5,7,7,8,8];

谢谢。

要从函数中删除递归,只需将递归调用替换为适当的变量赋值:

function findSingularElement1(arr) {
    if (arr.length < 3)
        throw('Invalid length of array.');

    var low = 0, high = arr.length - 1;

    while (low < high) {

        var mid = low + (high - low) / 2;

        if (mid % 2 === 0) {
            if (arr[mid] == arr[mid + 1]) {
                low = mid + 2;
            } else {
                high = mid;
            }
        } else {
            if (arr[mid] == arr[mid - 1]) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
    }
    return low == high ? arr[low] : null;
}
函数findSingularElement1(arr){
如果(arr.length<3)
throw('数组长度无效');
var低=0,高=arr.length-1;
while(低<高){
var中=低+(高-低)/2;
如果(中间%2==0){
如果(arr[mid]==arr[mid+1]){
低=中+2;
}否则{
高=中;
}
}否则{
如果(arr[mid]==arr[mid-1]){
低=中+1;
}否则{
高=中-1;
}
}
}
返回低==高?arr[低]:空;
}
也就是说,您的整个方法似乎过于复杂,您可以通过一个简单的循环轻松找到一个未配对的项:

for (var i = 0; i < array.length; i += 2)
    if (array[i] != array[i + 1])
        return array[i];
for(变量i=0;i

(假设数组已排序,并且每个项恰好出现一次或两次)。

要从函数中删除递归,只需使用适当的变量赋值替换递归调用:

function findSingularElement1(arr) {
    if (arr.length < 3)
        throw('Invalid length of array.');

    var low = 0, high = arr.length - 1;

    while (low < high) {

        var mid = low + (high - low) / 2;

        if (mid % 2 === 0) {
            if (arr[mid] == arr[mid + 1]) {
                low = mid + 2;
            } else {
                high = mid;
            }
        } else {
            if (arr[mid] == arr[mid - 1]) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
    }
    return low == high ? arr[low] : null;
}
函数findSingularElement1(arr){
如果(arr.length<3)
throw('数组长度无效');
var低=0,高=arr.length-1;
while(低<高){
var中=低+(高-低)/2;
如果(中间%2==0){
如果(arr[mid]==arr[mid+1]){
低=中+2;
}否则{
高=中;
}
}否则{
如果(arr[mid]==arr[mid-1]){
低=中+1;
}否则{
高=中-1;
}
}
}
返回低==高?arr[低]:空;
}
也就是说,您的整个方法似乎过于复杂,您可以通过一个简单的循环轻松找到一个未配对的项:

for (var i = 0; i < array.length; i += 2)
    if (array[i] != array[i + 1])
        return array[i];
for(变量i=0;i

(假设数组已排序,并且每个项目恰好出现一次或两次)。

我的答案,只是玩得开心而已

var numberArray = [1, 3, 6, 8, 9, 11, 16, 27, 33, 37, 56, 78];

function recursiveBinary(sortedArray, target, start, end) {
    var start = start || 0;
  var end = end || sortedArray.length;
    var middle = Math.floor((start + end) / 2);

    if (start > end) {
    return -1;
  }

  if (target === sortedArray[middle]) {
    return sortedArray[middle];
  } else if (target < sortedArray[middle]) {
    return recursiveBinary(sortedArray, target, start, middle - 1);
  } else if (target > sortedArray[middle]) {
    return recursiveBinary(sortedArray, target, middle + 1, end);
  }

}

var sum = recursiveBinary(numberArray, 9);
var numberArray=[1,3,6,8,9,11,16,27,33,37,56,78];
函数递归二进制(排序数组、目标、开始、结束){
var start=start | | 0;
var end=end | | sortedArray.length;
var middle=数学楼层((起点+终点)/2);
如果(开始>结束){
返回-1;
}
如果(目标===SorterDarray[中间]){
返回到Darray[中间];
}否则如果(目标阵列[中间]){
返回递归二进制(sortedArray,target,middle+1,end);
}
}
var sum=递归二进制(numberArray,9);

我的答案,只是玩得开心而已

var numberArray = [1, 3, 6, 8, 9, 11, 16, 27, 33, 37, 56, 78];

function recursiveBinary(sortedArray, target, start, end) {
    var start = start || 0;
  var end = end || sortedArray.length;
    var middle = Math.floor((start + end) / 2);

    if (start > end) {
    return -1;
  }

  if (target === sortedArray[middle]) {
    return sortedArray[middle];
  } else if (target < sortedArray[middle]) {
    return recursiveBinary(sortedArray, target, start, middle - 1);
  } else if (target > sortedArray[middle]) {
    return recursiveBinary(sortedArray, target, middle + 1, end);
  }

}

var sum = recursiveBinary(numberArray, 9);
var numberArray=[1,3,6,8,9,11,16,27,33,37,56,78];
函数递归二进制(排序数组、目标、开始、结束){
var start=start | | 0;
var end=end | | sortedArray.length;
var middle=数学楼层((起点+终点)/2);
如果(开始>结束){
返回-1;
}
如果(目标===SorterDarray[中间]){
返回到Darray[中间];
}否则如果(目标阵列[中间]){
返回递归二进制(sortedArray,target,middle+1,end);
}
}
var sum=递归二进制(numberArray,9);

使用递归完成的任何操作都可以用循环代替。递归能做而循环不能做的唯一一件事就是使代码变得简单和干净。 通过使用循环替换基本条件,可以在二进制搜索中删除递归

 function binarySearch(arr,ele){
  let low = 0;
  let high = arr.length-1;
  while(low<=high){
   let mid = Math.floor((low+high)/2) 
   if(arr[mid]==ele) 
     return true;
   else if(arr[mid]>ele)
     high = mid-1;
   else
     low = mid+1;
    }
  return false;
 }
函数二进制搜索(arr,ele){
设low=0;
让高=arr.length-1;
while(洛威尔)
高=中-1;
其他的
低=中+1;
}
返回false;
}

使用递归完成的任何操作都可以用循环代替。递归能做而循环不能做的唯一一件事就是使代码变得简单和干净。 通过使用循环替换基本条件,可以在二进制搜索中删除递归

 function binarySearch(arr,ele){
  let low = 0;
  let high = arr.length-1;
  while(low<=high){
   let mid = Math.floor((low+high)/2) 
   if(arr[mid]==ele) 
     return true;
   else if(arr[mid]>ele)
     high = mid-1;
   else
     low = mid+1;
    }
  return false;
 }
函数二进制搜索(arr,ele){
设low=0;
让高=arr.length-1;
while(洛威尔)
高=中-1;
其他的
低=中+1;
}
返回false;
}

“是”两个问题…)代替rec调用,只需更新
low
high
并循环
low是预期的结果
4
?@guest271314是的,在这种情况下预期的结果是
4
。如果您考虑递归实际上是如何工作的,将内容推到堆栈上等等,任何递归算法都可以用循环重写。@georg我在这里转圈(没有双关语)。你介意举个例子来回答吗?我开始眉来眼去了(两个问题都回答“是”)不需要rec调用,只需更新
low
high
并在