Как представить двоичное дерево с таблицами (HTML)?

Вот головоломка для смелых. Я был на этом в течение нескольких дней и просто не могу прийти с решением.

Я хотел выпустить что-то вроде этого:

Использование только HTML, CSS и PHP.

Я приблизился, но не совсем то, что ожидал. Вот код в PHP и вот вывод.

<table border="0">
<thead>
    <tr>
        <th>Cientoveintiochavos</th>
        <th>Seseintaicuatravos</th>
        <th>Treintaidosavos</th>
        <th>Dieciseisavos</th>
        <th>Octavos</th>
        <th>Cuartos</th>
        <th>Semifinales</th>
        <th>Final</th>
    </tr>
</thead>
<tbody>
<?php for($i=0;$i<256;$i++): ?>
    <tr>
        <?php for($n=0,$c=2;$n<8;$n++,$c*=2): ?>
            <?php 
            /*
            if(false){//$i == 0) {
                $rwspn = $c/2+1; 
                $iter = 0;
            } else {
                $rwspn = $c; 
                $iter = $c;//-$c/2+1;
            } 
            */
            $class = ($i%($c*2))?'par':'impar winner';
            if($i%$c==0):?>
                <td rowspan="<?=$c;?>" class="<?=$class;?>"><span><?php echo genRandomString();?></span></td>
            <?php endif; ?>
        <?php endfor; ?>
    </tr>   
<?php endfor; ?>
</tbody>
</table>

Если кто-то знает, как представить двоичное дерево или дендрограмму, или придумает более разумный код, пожалуйста, дайте мне знать!

3 ответа

Решение

Я сделал что-то вроде этого, используя divs вроде @HugoDelsing. То, как я справлялся со строками, состояло в том, чтобы разделить каждую пару на 4 вертикально сложенных блока:

  1. Первый игрок (граница снизу)
  2. Распорка между 1-м и 2-м игроками (граница справа)
  3. Второй игрок (граница снизу и граница справа)
  4. Проставка перед следующей парой (без границ)

Каждый из них получает 1/4 высоты пары *, а общая высота пары удваивается при перемещении вправо. Если у вас нет степени двойки, заполните слоты заполнителями, чтобы все уменьшилось до нужного уровня.

* Нижние границы будут сбрасывать высоту на 1, так что учитывайте это при оформлении ваших строк.

Другие заметки
Разделительные элементы div могут быть не нужны, но для меня они легко обрабатывают интервалы и заставляют разные столбцы правильно выстраиваться.

Я использовал встроенные стили, заполненные PHP для высоты, поэтому у меня не было произвольного предела глубины или расчетов, жестко запрограммированных в CSS.

Вот пример.

РЕДАКТИРОВАТЬ
Хорошо, вот кодез:

<style type="text/css">
    .round{
        float:left;
        width:200px;
    }
    .firstTeam, .secondTeam{
        border-bottom:1px solid #ccc;
        position:relative;
    }
    .firstSpacer, .secondTeam{
        border-right:1px solid #ccc;
    }
    .team{
        position:absolute;
        bottom: 4px;
        left: 8px;
    }
</style>
<div class="round">
    <div class="matchup">
        <div class="firstTeam" style="height:29px;"><div class="team">Team One</div></div>
        <div class="firstSpacer" style="height:30px;">&nbsp;</div>
        <div class="secondTeam" style="height:29px;"><div class="team">Team Two</div></div>
        <div class="secondSpacer" style="height:30px;">&nbsp;</div>
    </div>
    <div class="matchup">
        <div class="firstTeam" style="height:29px;"><div class="team">Team Three</div></div>
        <div class="firstSpacer" style="height:30px;">&nbsp;</div>
        <div class="secondTeam" style="height:29px;"><div class="team">Team Four</div></div>
        <div class="secondSpacer" style="height:30px;">&nbsp;</div>
    </div>
    <div class="matchup">
        <div class="firstTeam" style="height:29px;"><div class="team">Team Five</div></div>
        <div class="firstSpacer" style="height:30px;">&nbsp;</div>
        <div class="secondTeam" style="height:29px;"><div class="team">Team Six</div></div>
        <div class="secondSpacer" style="height:30px;">&nbsp;</div>
    </div>
    <div class="matchup">
        <div class="firstTeam" style="height:29px;"><div class="team">Team Seven</div></div>
        <div class="firstSpacer" style="height:30px;">&nbsp;</div>
        <div class="secondTeam" style="height:29px;"><div class="team">Team Eight</div></div>
        <div class="secondSpacer" style="height:30px;">&nbsp;</div>
    </div>
</div>
<div class="round">
    <div class="matchup">
        <div class="firstTeam" style="height:59px;"><div class="team">Team One</div></div>
        <div class="firstSpacer" style="height:60px;">&nbsp;</div>
        <div class="secondTeam" style="height:59px;"><div class="team">Team Three</div></div>
        <div class="secondSpacer" style="height:60px;">&nbsp;</div>
    </div>
    <div class="matchup">
        <div class="firstTeam" style="height:59px;"><div class="team">Team Five</div></div>
        <div class="firstSpacer" style="height:60px;">&nbsp;</div>
        <div class="secondTeam" style="height:59px;"><div class="team">Team Eight</div></div>
        <div class="secondSpacer" style="height:60px;">&nbsp;</div>
    </div>
</div>
<div class="round">
    <div class="matchup">
        <div class="firstTeam" style="height:119px;">&nbsp;</div>
        <div class="firstSpacer" style="height:120px;">&nbsp;</div>
        <div class="secondTeam" style="height:119px;">&nbsp;</div>
        <div class="secondSpacer" style="height:120px;">&nbsp;</div>
    </div>
</div>
<div class="round">
    <div class="matchup">
        <div class="firstTeam" style="height:239px;">&nbsp;</div>
    </div>
</div>

Похоже, ты почти там. Хорошо сделано! Я думаю, что выравнивание по центру вы хотите в CSS

td {
    vertical-align: middle;
}

Я не думаю, что вы можете заставить линии работать, используя границы. Вы можете попробовать для них фоновое изображение.

Я не буду использовать таблицу, но divs.

  • создайте контейнер столбца div с относительной / абсолютной позицией с фиксированной шириной (например, 200 пикселей) для каждого столбца.
  • Каждый контейнер столбца имеет внутренние div с высотой и высотой строки, равной удвоенному предыдущему контейнеру столбца
  • создайте длинное черное изображение вертикальной линии (длина по крайней мере вдвое меньше самой большой высоты внутренних элементов в любом столбце. Начните линию с горизонтальной линии шириной 200 пикселей влево (поверните L на 180 градусов). Оставьте примерно половину высота текста свободного места над горизонтальной линией на изображении, поэтому линия будет находиться под текстом.
  • установите это изображение в качестве фона для внутреннего div каждого контейнера столбца и поместите его в центр слева; повтор = нет;

Пример кода (без изображений)

<style type="text/css">
div.col { position:absolute;border:1px solid #f00;width:200px;top:0px; }
div.col1 { left:0px; }
div.col1 div { height:20px; line-height:20px; }
div.col2 { left:200px; }
div.col2 div { height:40px; line-height:40px; }
div.col3 { left:400px; }
div.col3 div { height:80px; line-height:80px; }
div.col4 { left:600px; }
div.col4 div { height:160px; line-height:160px; }
div.col5 { left:800px; }
div.col5 div { height:320px; line-height:320px; }
</style>


<div class='col1 col'>
    <div>player1</div>
    <div>player2</div>
    <div>player3</div>
    <div>player4</div>
    <div>player5</div>
    <div>player6</div>
    <div>player7</div>
    <div>player8</div>
    <div>player9</div>
    <div>player10</div>
    <div>player11</div>
    <div>player12</div>
    <div>player13</div>
    <div>player14</div>
    <div>player15</div>
    <div>player16</div>
</div>
<div class='col2 col'>
    <div>player1</div>
    <div>player3</div>
    <div>player5</div>
    <div>player7</div>
    <div>player9</div>
    <div>player11</div>
    <div>player13</div>
    <div>player15</div>
</div>
<div class='col3 col'>
    <div>player1</div>
    <div>player5</div>
    <div>player9</div>
    <div>player13</div>
</div>
<div class='col4 col'>
    <div>player1</div>
    <div>player9</div>
</div>
<div class='col5 col'>
    <div>player1</div>
</div>
Другие вопросы по тегам