js实现赛程
赛程生成的基本思路
赛程生成通常涉及循环赛或淘汰赛的编排,需要合理安排比赛顺序避免冲突。循环赛确保每支队伍与其他队伍至少交锋一次,淘汰赛则逐步淘汰队伍直至决出冠军。
循环赛算法实现
使用双循环法可以生成主客场赛程。将队伍列表分为两部分,通过旋转数组模拟对战组合。

function generateRoundRobin(teams) {
const schedule = [];
const numTeams = teams.length;
const half = Math.floor(numTeams / 2);
for (let round = 0; round < numTeams - 1; round++) {
const roundMatches = [];
for (let i = 0; i < half; i++) {
const home = teams[i];
const away = teams[numTeams - 1 - i];
if (home && away) {
roundMatches.push({ home, away });
}
}
schedule.push(roundMatches);
// 旋转数组(保留第一个元素)
teams.splice(1, 0, teams.pop());
}
return schedule;
}
淘汰赛算法实现
淘汰赛需要处理队伍数量不是2的幂次方的情况,通过首轮轮空实现平衡。

function generateKnockout(teams) {
const rounds = [];
let currentRound = [...teams];
while (currentRound.length > 1) {
const nextRound = [];
const matches = [];
for (let i = 0; i < currentRound.length; i += 2) {
if (i + 1 < currentRound.length) {
matches.push({
team1: currentRound[i],
team2: currentRound[i + 1]
});
nextRound.push(null); // 胜者待定
} else {
nextRound.push(currentRound[i]); // 轮空
}
}
rounds.push(matches);
currentRound = nextRound;
}
return rounds;
}
可视化赛程输出
将生成的赛程格式化为可读性更高的表格形式。
function printSchedule(schedule) {
schedule.forEach((round, index) => {
console.log(`Round ${index + 1}:`);
round.forEach(match => {
console.log(` ${match.home} vs ${match.away}`);
});
});
}
处理奇数队伍情况
当队伍数量为奇数时,自动添加轮空位保持算法稳定性。
function prepareTeams(rawTeams) {
const teams = [...rawTeams];
if (teams.length % 2 !== 0) {
teams.push(null); // 轮空标记
}
return teams;
}
完整调用示例
const teams = ['Team A', 'Team B', 'Team C', 'Team D'];
const preparedTeams = prepareTeams(teams);
const roundRobin = generateRoundRobin(preparedTeams);
printSchedule(roundRobin);
const knockout = generateKnockout(teams);
console.log(knockout);






