问题描述
我目前正在尝试修补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)]
}
当要比较的对象键很多时,可以通过设置其他优先级数组并按键的优先级顺序对元素进行比较来进一步简化此操作。