我需要以一种我不知道如何去做的方式遍历一棵树。我有一个对象代表一个锦标赛,其中有嵌套对象,其中包含要播放的匹配项。所以我总共有7个对象,第一个代表有两个孩子的FINAL,这两个孩子是SEMIFINALS,每个孩子有两个孩子,每个孩子都是QUARTERFINALS。它看起来像这样:
Match {
player1: undefined,
player2: undefined,
childrenLeft:
Match {
player1: undefined,
player2: undefined,
childrenLeft:
Match {
player1: 'John',
player2: 'Luke',
childrenLeft: undefined,
childrenRight: undefined },
childrenRight:
Match {
player1: 'Ann',
player2: 'Mark',
childrenLeft: undefined,
childrenRight: undefined } },
childrenRight:
Match {
player1: undefined,
player2: undefined,
childrenLeft:
Match {
player1: 'George',
player2: 'Mary',
childrenLeft: undefined,
childrenRight: undefined },
childrenRight:
Match {
player1: 'Sofie',
player2: 'Tom',
childrenLeft: undefined,
childrenRight: undefined }
}
}
决赛和半决赛的球员都没有定义,因为我们还没有参加四分之一决赛。
然后我有一个功能告诉计算机谁赢了比赛,所以玩家前进到下一轮。工作良好。最后我有一个函数返回我,这是下一个匹配的游戏,如下所示:
Match.prototype.nextMatch = function () {
if (this.player1 && this.player2) return this;
if (!this.player2 && this.childrenRight !== undefined) return this.childrenRight.nextMatch();
if (!this.player1 && this.childrenLeft !== undefined) return this.childrenLeft.nextMatch();
}
这个功能有效,但不是我想要的方式,因为它让我回到了右边的所有比赛,直到一个玩家到达决赛,然后它从左侧返回我的球员。
我希望这个功能首先让我回到第四个四分之一决赛,然后是第四个四分之一决赛,然后是第二个四分之一决赛,然后是第一个四分之一决赛,然后是第二个半决赛,然后是第一个半决赛,最后是决赛。 / p>
如果有人知道怎么做,我将不胜感激任何帮助!
答案 0 :(得分:0)
你可以使用这个函数,它有一个单独的递归函数来跟踪树中的深度,因此决定树中的潜在匹配是否比目前找到的更深。这样你肯定会得到树中最深的匹配:
Match.prototype.nextMatch = function () {
var next, nextDepth = -1;
(function recurse(match, depth = 0) {
if (match.player1 && match.player2 && depth > nextDepth) {
next = match;
nextDepth = depth;
}
if (!match.player1 && match.childrenLeft)
recurse(match.childrenLeft, depth + 1);
if (!match.player2 && match.childrenRight)
recurse(match.childrenRight, depth + 1);
})(this);
return next;
}
在下面的演示中,Mary和Ann可以参加“右侧”半决赛,但由于在四分之一决赛中仍然有比赛,该功能将返回其中一个,而不是Mary的一个和安:
function Match(p1, p2) {
this.player1 = p1;
this.player2 = p2;
this.childrenLeft = undefined;
this.childrenRight = undefined;
}
Match.prototype.nextMatch = function () {
var next, nextDepth = -1;
(function recurse(match, depth = 0) {
if (match.player1 && match.player2 && depth > nextDepth) {
next = match;
nextDepth = depth;
}
if (!match.player2 && match.childrenRight)
recurse(match.childrenRight, depth + 1);
if (!match.player1 && match.childrenLeft)
recurse(match.childrenLeft, depth + 1);
})(this);
return next;
}
var root = new Match();
root.childrenRight = new Match('Mary', 'Ann');
root.childrenLeft = new Match();
root.childrenLeft.childrenLeft = new Match('George', 'Mary');
root.childrenLeft.childrenRight = new Match('Sophie', 'Tom');
var nextMatch = root.nextMatch();
console.log('Next match: ', nextMatch.player1, nextMatch.player2);