Javascript 如何从数组中选择顺序不是随机的,而是数学的

Javascript 如何从数组中选择顺序不是随机的,而是数学的,javascript,Javascript,我不需要公式就可以做到这一点,但我正在努力创建一种数组选择方法,可以选择我称之为几乎随机的数组。原因是当数组以2的幂增长时,我需要在某个特定的位置进行选择。数组索引的内容并不重要 [0] // select index 0 [0,1] // select index 1 then 0 [0,1,2,3] // 3, 1, 2, 0 [0,1,2,3,4,5,6,7] // 7, 3, 5, 1, 6, 2, 4, 0 [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]

我不需要公式就可以做到这一点,但我正在努力创建一种数组选择方法,可以选择我称之为几乎随机的数组。原因是当数组以2的幂增长时,我需要在某个特定的位置进行选择。数组索引的内容并不重要

[0] // select index 0
[0,1] // select index 1 then 0
[0,1,2,3] // 3, 1, 2, 0
[0,1,2,3,4,5,6,7] // 7, 3, 5, 1, 6, 2, 4, 0
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] // 15,7,11,3,13,5,9,1,14,6,12,4,10,2,8
我终于想出了这个模式,因为当数组扩展到2的幂次时,它不会退化。选择保持不变。这与数组的排序无关,只是按照一定的顺序选择预排序的数组。我已经广泛地寻找可能的解决方案,但我已经有一段时间没有认真地做数学了,我相信这是需要的

我所看到的模式并不明显,但我会尝试进一步解释。它与二叉树有关。根目录下有
[0]

                     [0]
                    [0,1]
                  [0,1,2,3]
               [0,1,2,3,4,5,6,7]
   // for example
                ___ 20 ___
               /          \
              10          30
            /    \       /    \
           5      15    25    35
          / \    / \    / \   / \
         1   7  12 18  23 27 31  37
我需要创建第三个阵列,该阵列具有正确的插入顺序,而不会导致重新平衡

[20,30,10,35,15,25,5,37,18,27,7,31,12,23,1]

此选择模型继续随Btree增长,这将通过在自平衡树中插入这些值而导致树不重新平衡。

以下函数将按顺序将已排序的数组推入另一个数组,如果另一个数组实际上是AVL树,则不会导致重新平衡。这不是最有效的,但它展示了一个如何做到这一点的例子

var排序=[1,5,7,10,12,15,18,20,23,25,27,30,31,35,37];
log(“排序:”,排序)
功能插入平衡(SortDarray、avlTree){
var大小=分拣机的长度;
var结果=avlTree;
使用的var指数=[];
函数半索引(深度){
var切片=数学功率(2,深度);
对于(变量i=1;ilog(“avlTree”,someEmptyAvlTree)我最终找到了一种更好的休闲模式,它更容易在代码中实现。它也不会降解。我要说的是,DMOS方法也同样重要。我最终发现,赔率模式甚至指数轮换都有帮助

            root             40
                  /                        \
                20                          60 
           /            \              /          \
           10           30           50           70
         /    \       /    \       /    \        /     \
        5     15     25    35     45    55      65     75
       / \   /  \   / \    / \   /  \   /  \   /  \   /  \
      3  7  12  17 23  27 33 37 43  47 52  57 62  67 72  77
首先将每行分隔成一个数组。如果从平衡的BTree中提取,则数组将已经从最小到最大排序

这是我实际使用的代码

// array holding all elements
const allArray = [[40],[20,60],[10,30,50,70],[5,15,25,35,45,55,65,75],
                 [3,7,12,17,23,27,33,37,43,47,52,57,62,67,72,77]];
// create sorted reverse index array
const refA = [];
for (let i = 0; i < allArray.length; i++) {
    refA.push([]);
    for(let j = allArray[i].length - 1; j >= 0; j--) {
        refA[i].push(j);
    }
}
const fillRefA = (prev: number[], current: number[]): number[] => {
    const a = [];
    const prefAOdds = prev.filter((val: number) => (val % 2) !== 0);
    const prefAEvens = prev.filter((val: number) => (val % 2) === 0);
    const currentAOdds = current.filter((val: number) => (val % 2) !== 0);
    const currentAEvens = current.filter((val: number) => (val % 2) === 0);
    const newAOdds = currentAOdds.filter((val: number) => !prefAOdds.includes(val));
    const newAEvens = currentAEvens.filter((val: number) => !prefAEvens.includes(val));

    for (let i = 0; i < prefAOdds.length; i++) {
        a.push(newAOdds[i]);
        a.push(prefAOdds[i]);
    }
    for (let i = 0; i < prefAOdds.length; i++) {
        a.push(newAEvens[i]);
        a.push(prefAEvens[i]);
    }
    return a;
};

for (let i = 2; i < refA.length; i++) {
    refA[i] = fillRefA(refA[i - 1], refA[i]);
}
// Then finally put all the arrays into a master array in order of proper insertion.
const final = [];
for (let i = 0; i < allArray.length; i++) {
    for (let j = 0; j < allArray[i].length; j++) {
        final.push(a[i][refA[i][j]]);
    }
}

由于阵列相对于其长度缩短,因此没有明显的模式!我希望我能上传这张照片。它来自一棵树。但我会尝试解释更多。什么是输入和输出?给定一个数组,获取一个迭代器,该迭代器返回插入到不会导致重新平衡的btree中的对象?@DMoses,数组的内容并不重要。我已经有了一个方法,可以把每一层都拉出来放到一个数组中,它们已经按照自平衡树排序了。我希望从每个数组中选取项目,将其放入主数组中,这样在插入数组中的每个项目时不会导致树重新平衡。这很好,但并不完全是我想要的。我不是要创建一个数组,其中的项可以在不重新平衡的情况下插入。我要找的是一种方法,它可以按照上面所述的顺序从排序数组中选择项,然后推送到主数组。我可以使用这个值数组,它不是一个非常平衡的索引插入方法。我的意思是,如果你想使用迭代器next()方法或诸如此类的方法,你需要根据自己的需要稍微重新安排一下。@mjwrazor我更新了答案,以展示一个示例,说明如何将相同的代码插入到某个AVL树中。我实际上没有AVL树实现,所以我使用数组来模拟它。我认为这更接近。我会继续努力,看看我是否能得到确切的输出,我正在寻找。但如果我知道如何从这段代码中获得特定的输出,我会将此标记为答案。并在下面发布我的更改。我发现你的答案非常有用,可以用作答案,但我还是用我自己的方法。
//first you cannot work this method on the first item so you need to start at index of 2
// second you have to break evens and odds up but keep the order of previous insertion
[1,0] // odds [1], evens [0]
[3,2,1,0] // odds [3,1], evens [1,0];
// but extract previous array odds and evens 
// so [3], [2]. and you have the previous odds and evens [1], [0]
// and insert them in order, odds then evens. 
[3,1,2,0]
// again with the next row
[7,5] [6,4] [3,1] [2,0]
[7,3,5,1,6,2,4,0] // first you take the current then the previous
// and the next row. 
  [15,13,11,9] [14,12,10,8] [7,3,5,1] [6,2,4,0]
  [15,7,13,3,11,5,9,1,14,6,12,4,10,2,8,0]

// This way no same node is on a branch is filled up before all nodes
// on the row at least have 1 filled then continue filling the leftovers.
// final insertion array
[40,60,20,70,30,50,10,75,35,55,15,65,25,45,5,77,37,67,17,57,27,47,
7,72,33,62,23,52,12,43,3]