使用next和prev值对列表进行排序

时间:2017-06-16 09:40:54

标签: javascript algorithm sorting

我的对象的值为id, next, prevnextprev的值为id的值。这些对象处于相当任意的顺序。我希望按照以下顺序获取它们:列表中没有前一个对象的对象位于第一位,然后是第一个对象的id为下一个值的对象,依此类推。

  • sort函数应返回列表列表
  • 如果列表中有不同的部分无法连接,那么这些部分将分为两个单独的列表。 (可以这么说:我们有2个结局和2个开头)
  • 0表示没有上一个/下一个
  • 排序功能在复杂性方面应尽可能高效
  • 伪代码没问题,不需要Javascript



let list = [
{"id": 181, "next": 182, "prev": 231},
{"id": 182, "next": 253, "prev": 181},
{"id": 230, "next": 231, "prev": 0},
{"id": 231, "next": 181, "prev": 230},
{"id": 253, "next": 254, "prev": 182},
{"id": 254, "next": 0, "prev": 253},
]

console.log("unordered", list.map(x => x.id))
let falsesorted = sortByNextPrev(list);
falsesorted.forEach(sub => {
  console.log(sub.map(x => x.id));
});

function sortByNextPrev(list){
 var sorted = list.reduce((acc,l) => {
     let last = acc[acc.length-1];
    if(last.length === 0 || last[last.length-1].next === l.id){
        last.push(l)
    }
    else if(last[0].prev === l.id){
        last.unshift(l);
    }
    else{
        acc.push([l]);
    }
    return acc;
},[[]]);
return sorted;
}




我的功能显然无法达到我想要的效果。 我尝试实现的顺序是230,231,181,182,253,254

我试图绕过它,但我还没有找到有效的解决方案。我想我可以建立一个非常愚蠢的功能,但我不愿意。

1 个答案:

答案 0 :(得分:0)

只需使用查找函数并从第一个元素开始,将它们一个接一个地放入结果数组中。查找可以通过循环简单地完成,在排序数组中使用二进制搜索,或使用查找表进行优化。

让我们选择最后一种方法,我们需要一次迭代才能找到第一个元素:

const byId = new Map();
const firsts = [];
for (const el of list) {
    byId.set(el.id, el);
    if (!el.prev) firsts.push(el);
}
const results = firsts.map(first => {
    const result = [];
    for (let x = first; x != null; x = byId.get(x.next))
        result.push(x);
    return result;
});