简体   繁体   中英

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

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;
},

水平树

Any suggestion would be really helpful.

You'll also need to cover the case when the tree is not perfect, ie 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM