JavaScript 找到数组的中位数索引
理解如何在JavaScript中找到数组的中位数索引的复杂性对于寻求揭示数据操作的奥秘的开发者来说具有重要意义。中位数是一个统计的集中趋势度量,它提供了有关数据集的分布和平衡的有价值的洞察力。借助JavaScript的多功能能力,利用算法来确定数组的中位数索引揭示了从复杂数据集中分析和提取有价值信息的可能性。在本文中,我们踏上一段旅程,探索确定JavaScript数组的中位数索引的一步一步的过程,深入了解那些探索者能够解锁他们数据数组中隐藏宝石的鲜为人知的技术和函数。
问题陈述
创建一个JavaScript算法,以找到未排序整数数组中中位数值的索引。对于长度为奇数的数组,中位数是位于中间索引的元素。对于长度为偶数的数组,中位数是最接近两个中央元素平均值的元素。该算法应该高效处理任意大小的数组,并具有最佳的时间复杂度来找到所需的索引。
样本输入 –
Array: [7, 12, 5, 3, 9, 2, 15, 8]
示例输出 –
Index of the element closest to the median: 4
方法
在本文中,我们将看到一些不同的方法来解决上述JavaScript问题:
- 排序方法
 - 
QuickSelect算法
 - 
中值中的中值方法
 - 
计数排序算法
 
方法1:排序方法
为了找到未排序数组中最接近中值的元素的索引,我们采用排序方法。首先,通过将数组长度除以2来计算中值索引。使用一个名为calculateMedian的辅助函数,我们对数组进行排序,并根据其长度确定中值。然后,我们初始化最接近索引(closestIndex)和最小差值(minDiff)的变量。从索引1开始,我们遍历数组,将每个元素的绝对差值与中值的当前最小差值进行比较。如果差值较小,则更新closestIndex和minDiff。最后,我们返回closestIndex,表示最接近中值的元素的索引。该方法考虑了绝对差值,无论元素的尺寸如何,均保证了接近性。
示例
给定的代码包含三个函数:findMedianValue、calculateMedian和findIndex。findMedianValue通过使用calculateMedian和遍历数组来找到数组中最接近中值的元素。calculateMedian对数组进行排序,并计算中间元素来确定中值。findIndex在数组中找到给定元素的索引。在代码中,一个数组被定义,并使用findMedianValue找到中值元素,然后与findIndex一起确定其索引。结果打印到控制台。
function findMedianValue(arr) { 
   const median = calculateMedian(arr); 
   let medianElement = 0; 
   let minDiff = Math.abs(arr[0] - median); 
   for (let i = 1; i < arr.length; i++) { 
      const diff = Math.abs(arr[i] - median); 
      if (diff < minDiff) { 
         minDiff = diff; 
         medianElement = arr[i]; 
      } 
   } 
   return medianElement; 
} 
function calculateMedian(arr) { 
   const sortedArr = arr.slice().sort((a, b) => a - b); 
   const length = sortedArr.length;
   if (length % 2 === 0) { 
      const middle = length / 2; 
      return (sortedArr[middle - 1] + sortedArr[middle]) / 2; 
   } else { 
      const middle = Math.floor(length / 2); 
      return sortedArr[middle]; 
   } 
} 
function findIndex(arr,el){ 
   let n=arr.length; 
   for(let i=0;i<n;i++){ 
      if(arr[i]==el) 
      return i; 
   } 
   return -1; 
} 
const arr = [1, 7, 3, 6, 5, 6]; 
const medianElement=findMedianValue(arr); 
const medianIndex=findIndex(arr,medianElement); 
console.log("Median element index:", medianIndex);  
console.log("Median element:", medianElement);
输出
以下是控制台输出内容:
Median element index: 3
Median element: 6
方法2:Quickselect算法
在JavaScript中,要找到未排序数组中中间元素的索引,我们可以使用快速选择算法。这涉及定义一个快速选择函数,该函数递归地对数组进行分区,直到找到所需的元素为止。我们选择一个基准元素,根据基准重新排列数组,并将基准索引与所需索引进行比较。如果它们匹配,我们返回索引。如果基准索引较大,我们在左侧子数组上递归调用快速选择;如果较小,我们在右侧子数组上调用它。这个过程将继续,直到找到所需的元素为止。该算法的时间复杂度为O(n),使它成为在未排序数组中找到中位数或最接近中位数的元素的高效解决方案。
示例
给定的代码包括找到数组的中位数和确定最接近中位数的元素索引的函数。”分区”函数选择一个基准元素并重新排列数组。”quickSelect”递归地找到第k个最小的元素。”findClosestToMedian”计算中位数,迭代数组并更新最接近的元素。”findIndex”迭代数组以找到给定元素的索引。在示例用法中,使用”findClosestToMedian”找到最接近中位数的元素,并使用”findIndex”找到其索引,然后将其打印到控制台。
function partition(arr, low, high) { 
   const pivot = arr[high]; 
   let i = low - 1; 
   for (let j = low; j < high; j++) { 
      if (arr[j] <= pivot) { 
         i++; 
         [arr[i], arr[j]] = [arr[j], arr[i]]; 
      } 
   } 
   [arr[i + 1], arr[high]] = [arr[high], arr[i + 1]]; 
   return i + 1; 
} 
function quickSelect(arr, low, high, k) { 
   if (low === high) { 
      return arr[low]; 
   } 
   const pivotIndex = partition(arr, low, high); 
   if (k === pivotIndex) { 
      return arr[k]; 
   } else if (k < pivotIndex) { 
      return quickSelect(arr, low, pivotIndex - 1, k); 
   } else { 
      return quickSelect(arr, pivotIndex + 1, high, k); 
   } 
} 
function findClosestToMedian(arr) { 
   const n = arr.length; 
   const medianIndex = Math.floor(n / 2); 
   const median = quickSelect(arr, 0, n - 1, medianIndex); 
   let closestValue=0
   let closestDiff = Math.abs(arr[0] - median); 
   for (let i = 1; i < n; i++) { 
   const diff = Math.abs(arr[i] - median); 
      if (diff < closestDiff) { 
         closestDiff = diff; 
         closestValue=arr[i];
      } 
   } 
   return closestValue; 
} 
function findIndex(arr,el){
   let n=arr.length;
   for(let i=0;i<n;i++){
      if(arr[i]==el)
      return i;
   }
   return -1;
}
// Example usage: 
const array = [5, 10, 2, 8, 3, 6]; 
const arrayCopy=JSON.parse(JSON.stringify(array));
const medianElement = findClosestToMedian(array);
const medianIndex=findIndex(arrayCopy,medianElement);
console.log("Median element index:", medianIndex); 
console.log("Median element:", medianElement);
输出
以下是控制台输出内容−
Median element index: 5
Median element: 6
方法3:中位数中位数
使用JavaScript的中位数中位数算法找到未排序数组的中位数或最接近中位数的元素,按照以下步骤进行。首先,定义主要函数findMedianIndex,并处理数组为空或只包含一个元素的情况。将中位数索引计算为数组长度除以2的底部值。创建一个分区辅助函数,该函数递归地应用中位数中位数算法以找到枢轴索引。使用枢轴索引将数组分割成两个子数组。根据中位数索引确定继续搜索的子数组,并相应地更新开始或结束索引。最后,对数组调用findMedianIndex函数以获取所需索引。
示例
findMedian函数使用辅助函数来查找数组的中位数元素。swap函数交换元素,partition函数将数组围绕枢轴元素进行分区,findMedianOfMedians函数递归地查找中位数中位数。findMedian函数计算中位数索引并返回中位数元素。在示例用法中,findMedian和findIndex函数在数组及其副本上调用以找到中位数元素和其索引,结果记录在控制台上。
function findMedian(arr) { 
   // Helper function to swap two elements in the array 
   function swap(arr, i, j) { 
      const temp = arr[i]; 
      arr[i] = arr[j]; 
      arr[j] = temp; 
   } 
   // Helper function to partition the array around the pivot 
   function partition(arr, left, right, pivotIndex) { 
      const pivotValue = arr[pivotIndex]; 
      let partitionIndex = left; 
      // Move the pivot to the rightmost position 
      swap(arr, pivotIndex, right); 
      for (let i = left; i < right; i++) { 
         if (arr[i] < pivotValue) { 
            swap(arr, i, partitionIndex); 
            partitionIndex++; 
         } 
      } 
      // Move the pivot back to its final position 
      swap(arr, partitionIndex, right); 
      return partitionIndex; 
   } 
   // Helper function to find the median of medians recursively 
   function findMedianOfMedians(arr, left, right, targetIndex) { 
      // If the array is small, find the median directly 
      if (right - left < 5) { 
         arr = arr.slice(left, right + 1).sort((a, b) => a - b); 
         return left + Math.floor((right - left) / 2); 
      } 
      // Divide the array into groups of size 5 and find the median of each group 
      for (let i = left; i <= right; i += 5) { 
         const groupRight = Math.min(i + 4, right); 
         const medianIndex = findMedianOfMedians(arr, i, groupRight, Math.floor((groupRight - i) / 2)); 
         swap(arr, medianIndex, left + Math.floor((i - left) / 5)); 
      } 
      // Find the median of medians recursively 
      const medianOfMediansIndex = findMedianOfMedians(arr, left, left + Math.ceil((right - left) / 5) - 1, Math.floor((right - left) / 10)); 
      // Partition the array around the median of medians 
      const pivotIndex = partition(arr, left, right, medianOfMediansIndex); 
      // Compare the pivot index with the target index 
      if (pivotIndex === targetIndex) { 
         return pivotIndex; 
      } else if (targetIndex < pivotIndex) { 
         return findMedianOfMedians(arr, left, pivotIndex - 1, targetIndex); 
      } else { 
         return findMedianOfMedians(arr, pivotIndex + 1, right, targetIndex);
      } 
   } 
   // Calculate the median index based on the array length 
   const medianIndex = Math.floor((arr.length - 1) / 2); 
   // Find the index of the median element using the Median of Median algorithm 
   const medianElementIndex = findMedianOfMedians(arr, 0, arr.length - 1, medianIndex); 
   return arr[medianElementIndex];
   return medianElementIndex; 
} 
function findIndex(arr,el){ 
   let n=arr.length; 
   for(let i=0;i<n;i++){ 
      if(arr[i]==el) 
      return i; 
   } 
   return -1; 
} 
// Example usage: 
const array = [7, 2, 9, 4, 5, 6, 1, 3, 8];
const arrayCopy=JSON.parse(JSON.stringify(array)); 
const medianElement = findMedian(array); 
const medianIndex=findIndex(arrayCopy,medianElement); 
console.log("Median element index:", medianIndex);  
console.log("Median element:", medianElement);
输出
以下是控制台输出:
Median element index: 5
Median element: 6
方法4:计数排序
使用JavaScript的计数排序算法来寻找未排序数组中的中位数元素的索引,按照以下步骤进行:初始化一个长度为最大元素加一的计数数组,递增计数数组中每个元素的计数,通过计算累积频率修改计数数组,根据数组长度确定中位数索引,遍历计数数组找到累积和超过或等于中位数索引的元素索引,并将找到的元素索引作为中位数索引返回。这种方法高效处理小范围已知输入值,时间复杂度为O(n+k),其中n是数组长度,k是值的范围。
示例
提供的代码使用计数排序来确定数组的中位数。它找到最大值和最小值,初始化了一个计数数组,并基于最小值递增计数。另一个循环通过比较运行计数来找到中位数。索引加上最小值表示中位数。代码还包括一个findIndex函数。它通过定义一个示例数组,创建一个深拷贝,并找到中位数及其索引来演示用法。结果都会打印到控制台。
function findMedian(arr) {
   // Counting Sort
   const max = Math.max(...arr);
   const min = Math.min(...arr);
   const countArray = Array(max - min + 1).fill(0);
   for (let i = 0; i < arr.length; i++) {
      countArray[arr[i] - min]++;
   }
   let sum = 0;
   for (let i = 0; i < countArray.length; i++) {
      sum += countArray[i];
      if (sum >= Math.ceil(arr.length / 2)) {
         return i + min; // Value at the median index
      }
   }
}
function findIndex(arr,el){ 
   let n=arr.length ;
   for(let i=0;i<n;i++){ 
      if(arr[i]==el) 
      return i; 
   } 
   return -1; 
} 
// Example usage:
const array = [7, 2, 5, 1, 8, 4];
const arrayCopy=JSON.parse(JSON.stringify(array)); 
const medianElement = findMedian(array);
const medianIndex=findIndex(arrayCopy,medianElement); 
console.log("Median element index:", medianIndex);  
console.log("Median element:", medianElement);
输出
以下是控制台输出:
Median element index: 5
Median element: 4
结论
在 JavaScript 中寻找数组的中位数索引的探索揭示了一个错综复杂但又引人入胜的挑战。解题的关键在于算法和计算的深奥领域,需要明智的方法来实现精确度。通过采用鲜少使用的方法和发掘 JavaScript 的隐秘深处,人们可以揭示难以捉摸的中位数索引,丰富数据处理和分析的领域。总之,这个神秘的努力照亮了 JavaScript 的无限可能性,呼唤勇敢的程序员拥抱未知的数组探索领域,并揭开中位数索引的谜团。
极客笔记