[十大算法JavaScript的实现] 五、BFPRT线性查找

目录

一、思想

二、实现

三、结果


一、思想

快速排序(https://www.yuque.com/docs/share/7f809e06-0724-49d9-b37d-41f3b4d32b85#)的扩展。取五分中位数位基准值,减少时间复杂度。

二、实现

js

// k / n-k+1
 //找到list中第k大的数值
 let BFPRT = (idxList, k) => {
  // 找打五分位中位数 (位置及数值)
  let base = getFivePartMiddle(idxList);
  let leftL = [],
   rightL = [];
  for (let i = 0, item; item = idxList[i++];) {
   if (item.idx == base.idx) continue
   if (item.val >= base.val) {
    leftL.push(item);
   } else {
    rightL.push(item);
   }
  }
  if (leftL.length == k - 1) return base.val;0
  if (leftL.length < k - 1) {//左边序列第k大的值
   return BFPRT(rightL, k - leftL.length - 1); //右边序列第k-L-1大的值
  } else {
   return BFPRT(leftL, k);
  }
 }
 //获取五分位中位数
 let getFivePartMiddle = (idxList) => {
  if (idxList.length > 5) {
   let num = Math.floor(idxList.length / 5);
   let mod = idxList.length % 5;
   let list_ = []; //中位数组成的数组
   let i = 0;
   for (; i < num; i++) {
    let lst = idxList.slice(i * 5, (i + 1) * 5);
    list_.push(findMiddleOf5(lst));
   }
   if (mod > 0) list_.push(findMiddleOf5(idxList.slice(i * 5, i * 5 + mod)));
   return getFivePartMiddle(list_)
  } else {
   return findMiddleOf5(idxList);
  }
 }
 // 快速排序
 let quickSort = (list) => {
  let l = list.length;
  if (list.length <= 1) { return list }; // 排序数组小于等于一个元素则直接返回
  let baseIndex = Math.floor(l / 2);
  let baseValue = list[baseIndex].val;
  let leftList = [],
   rightList = [];
  for (let i = 0; i < l; i++) {
   if (i == baseIndex) continue;
   if (list[i].val <= baseValue) {
    leftList.push(list[i]) //小于基准数据放左边
   } else {
    rightList.push(list[i]) //大于于基准数据放右边
   }
  }
  return quickSort(leftList).concat([list[baseIndex]]).concat(quickSort(rightList));
 }
 //找个5个数组成的数组的中值(值与索引)
 let findMiddleOf5 = (idxList) => {
  return quickSort(idxList)[Math.ceil(idxList.length / 2) - 1];
 }
 let input = [1, 2, 3, 4, 5, 6, 12, 56, 3, 5, 9888, 1234, 52, 62, 23, 89, 96, 42, 31212, 125];
 let k = 6;
 let idxInput = (function(list) {
  let idxInput = [];
  for (let i = 0; i < list.length; i++) {
   idxInput.push({
    val: list[i],
    idx: i
   })
  }
  return idxInput
 })(input)
 console.log('找到数列中第K大的数:');
 console.log('list: ', input);
 console.log('K: ', k);
 let result = BFPRT(idxInput, k);
 console.log('result: ', result);

三、结果

image.png

你可能感兴趣的:(数据结构与算法,算法,JavaScript,BFPRT线性查找)