Home > OS >  How to find element position based on number of elements in a tree like structure?
How to find element position based on number of elements in a tree like structure?

Time:10-11

I am looking for a solution for creating a dynamic Tree like structure from Flat Array.

Sample Input -> [1, 2, 3, 4, 5, 6, 7]

What i am able to determine is Number of columns and Row need. But stuck at finding a pattern for the position of each element, so that they can be positioned with taking proper spacing.

** During iteration i will get column and index info

Ex1: Num 4 element will go to 3rd column and 2nd row.

Ex2: If there were 3 elements in input position would be->

1st element -> 1 no column and 2 no row

2nd element -> 2 no column and 1 no row

3rd element -> 2 no column and 3 no row

Determined number of columns and rows by below way ->

getColumnLength() {
  if (this.list.length <= 1) {
    return 1;
  }
  if (this.list.length <= 3) {
    return 2;
  }
  for (let i = 2; i <= this.list.length; i  ) {
    let columnLength = Math.pow(2, i);
    if (columnLength >= this.list.length) {
      return i;
    }
  }
},
getRowLength() {
  return Math.pow(2, this.getColumnLength)   1;
},

Horizontal Tree

Any suggestion would be really helpful.

CodePudding user response:

You'll also need to cover the case when the tree is not perfect, i.e. when the leaves of the tree are not all on the same level. In that case the calculation of getRowLength is not correct, as it will count some rows which remain empty. The number of rows is really the size of the list: each value in the list is displayed on its own row, and no other rows are needed.

There is also a nifty Math.clz32 method with which you can easily get the number of used bits in a number. This number of bits maps nicely to the number of columns.

You can get the row/col information of a cell during an in-order traversal.

Here is a demo which makes such in-order traversal using a generator. That iterator will yield the currently visited value's position information (row and column):

const tree = {
    * iterate(index=0, column=1, cursor={row: 1}) {
        if (index >= this.list.length) return;
        yield* this.iterate(index * 2   1, column   1, cursor);
        yield { index, value: this.list[index], row: cursor.row  , column };
        yield* this.iterate(index * 2   2, column   1, cursor);
    },
    getColumnLength() {
        return 32 - Math.clz32(this.list.length);
    },
    displayInDOM(container) { // Demo that uses above iterate method
        container.innerHTML = `<table>${`<tr>${"<td></td>".repeat(this.getColumnLength())}<\/tr>`.repeat(this.list.length)}<\/table>`;
        const rows = container.children[0].rows;
        for (const {row, column, value} of this.iterate()) {
            rows[row - 1].cells[column - 1].textContent = value;
        }
    }
}

// Demo
tree.list = [1,2,3,4,5,6,7,8,9];
tree.displayInDOM(document.querySelector("div"));
table { border-collapse: collapse }
td { vertical-align: middle; text-align: center; min-width: 24px; border: 1px solid; }
<div></div>

  • Related