尝试转换我的Quicksort函数,以便它可以处理对象数组并按对象内的值排序

问题描述

我目前正在尝试修补Quicksort函数,以便在存在具有相同排序目标但ID不同的对象数组时测试现实生活中的问题。

下面是我的两个不同的代码,其中枢轴选择机制彼此不同。

//first Code


function quickSort(array) {
  if (array.length === 1) return array; // base case
  let pivot = array[array.length - 1]; 
  let leftArr = [];
  let rightArr = [];

  for(let el of array) {
      if (el.num < pivot.num) {
          leftArr.push(el); 
      } else {
          rightArr.push(el); 
      }
  }
  console.log(rightArr);
  console.log(leftArr);

  if (leftArr.length > 0 && rightArr.length > 0) {
    return [...quickSort(leftArr),pivot,...quickSort(rightArr)] 
  } else if (leftArr.length > 0) {
    return [...quickSort(leftArr),pivot]
  } else {
    return [pivot,...quickSort(rightArr)] 
  }
}
// second Code 

function quickSort2(arr) {
  if (!arr.length) {
    return arr;
  }
  let pivotIdx = Math.floor(Math.random() * (arr.length));
  let pivot = arr[pivotIdx];
  let head = [];
  let tail = [];
  let exceptPivot = arr.slice(0,pivotIdx).concat(arr.slice(pivotIdx + 1));
  for (let el of exceptPivot) {
    if (el.num <= pivot.num) {
      head.push(el)
    } else {
      tail.push(el)
    }
  }
  // return quickSort1(head).concat([pivot].concat(quickSort1(tail)));
  return [...quickSort1(head),...quickSort1(tail)];
};

下面是测试:

let test = [
  {id: 4,num: 21},{id: 7,num: 22},{id: 12,num: 24},{id: 5,num: 100},{id: 6,{id: 32,num: 14},{id: 19,num: 15},{id: 23,num: 16},{id: 1,{id: 42,{id: 56,{id: 74,num: 100}
]

对于第一个代码,我得到很多堆栈作为结果。最终根本无法排序。 对于第二个代码,我仅获得数组结果。

您能否指出我未考虑的逻辑并在代码中出现毛刺? 预先谢谢你。

解决方法

对于第一个代码,您的代码会产生无限循环,因为您没有考虑 el.num === ivot.num 时会发生什么。例如,

array = [
  {id: 4,num: 21},{id: 7,num: 22},{id: 12,num: 24},{id: 19,num: 15},{id: 23,num: 16},{id: 1,num: 15}
]

将永远继续使用其他逻辑。

else {
    return [pivot,...quickSort(rightArr)] 
}

现在,解决方案很简单,请检查2个元素的 num 键是否相等。例如:

function quickSort(array) {
  if (array.length <= 1) return array; // note that array.length === 0 is also base case
  
  let pivot = array[array.length - 1]; 
  let leftArr = [];
  let rightArr = [];
  let sameArr = []; // to save elements with same num value
  for(let el of array) {
      if (el.num < pivot.num) {
          leftArr.push(el); 
      } else if(el.num > pivot.num) {
          rightArr.push(el); 
      } else {
          sameArr.push(el);
      }
  }

  return [...quickSort(leftArr),...sameArr,...quickSort(rightArr)]
}

但是,当两个元素具有相同的 num 值但具有不同的 id 值时会发生什么呢? 这取决于您的用例,哪一个具有更高的优先级 num id

如果您要先根据 id -值进行排序,然后再根据 num -值进行排序:

function quickSort(array) {
  if (array.length <= 1) return array; // base case
  
  let pivot = array[array.length - 1]; 
  let leftArr = [];
  let rightArr = [];
  let sameArr = [];
  for(let el of array) {
      if (el.id < pivot.id) {
          leftArr.push(el); 
      } else if(el.id > pivot.id) {
          rightArr.push(el); 
      } else {
        if (el.num < pivot.num) {
          leftArr.push(el);
        } else if (el.num > pivot.num) {
          rightArr.push(el);
        } else {
          sameArr.push(el);
        }
      }
  }

  return [...quickSort(leftArr),...quickSort(rightArr)]
}

如果您要首先基于 num 个值进行排序,然后再根据 id 个值进行排序:

function quickSort(array) {
  if (array.length <= 1) return array; // base case
  
  let pivot = array[array.length - 1]; 
  let leftArr = [];
  let rightArr = [];
  let sameArr = [];
  for(let el of array) {
      if (el.num < pivot.num) {
          leftArr.push(el); 
      } else if(el.num > pivot.num) {
          rightArr.push(el); 
      } else {
        if (el.id < pivot.id) {
          leftArr.push(el);
        } else if (el.id > pivot.id) {
          rightArr.push(el);
        } else {
          sameArr.push(el);
        }
      }
  }

  return [...quickSort(leftArr),...quickSort(rightArr)]
}

当要比较的对象键很多时,可以通过设置其他优先级数组并按键的优先级顺序对元素进行比较来进一步简化此操作。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...