Home > Blockchain >  Get index of each root on level wise in tree data structure
Get index of each root on level wise in tree data structure

Time:02-22

Hey I am working on tree data structure. I want to know can we get index of each node in level wise. I below diagram represent how I want the value index. Level A or B represent node value and index value represent index value

                                     Node
                     |                 |                 |
Level A ->           1                 2                 3
index value->        0                 1                 2
                 |       |          |      |          |     |
                 |       |          |      |          |     |
Leve B->         4       5          6      7          8     9
index value->    0       1          2      3          4     5

....// more level
       

How can we achieved index in each level wise. I am adding my logic how I am adding value in each level wise. Could you someone suggest how can I achieve this?

var baseNode: LevelIndex = LevelIndex()
var defaultId = "1234"
fun main() {
    val list = getUnSortedDataListForLevel()
    val tempHashMap: MutableMap<String, LevelIndex> = mutableMapOf()
    list.forEach { levelClass ->
        levelClass.levelA?.let { levelA ->
            val levelOneTempHashMapNode = tempHashMap["level_a${levelA}"]
            if (levelOneTempHashMapNode != null) {
                if (defaultId == levelClass.id && levelOneTempHashMapNode is LevelOne) {
                    levelOneTempHashMapNode.defaultValue = true
                }
                return@let
            }
            val tempNode = LevelOne().apply {
                value = levelA
                if (defaultId == levelClass.id) {
                    defaultValue = true
                }
            }
            baseNode.children.add(tempNode)
            tempHashMap["level_a${levelA}"] = tempNode
        }

        levelClass.levelB?.let { levelB ->
            val levelTwoTempHashMapNode = tempHashMap["level_a${levelClass.levelA}_level_b${levelB}"]
            if (levelTwoTempHashMapNode != null) {
                if (defaultId == levelClass.id && levelOneTempHashMapNode is LevelTwo) {
                    levelTwoTempHashMapNode.defaultValue = true
                }
                return@let
            }
            val tempNode = LevelTwo().apply {
                value = levelB
                if (defaultId == levelClass.id) {
                    defaultValue = true
                }
            }
            val parent =
                tempHashMap["level_a${levelClass.levelA}"] ?: baseNode
            parent.children.add(tempNode)
            tempHashMap["level_a${levelClass.levelA}_level_b${levelB}"] =
                tempNode
        }

        levelClass.levelC?.let { levelC ->
            val tempNode = LevelThree().apply {
                value = levelC
                if (defaultId == levelClass.id) {
                    defaultValue = true
                }
            }
            val parent =
                tempHashMap["level_a${levelClass.levelA}_level_b${levelClass.levelB}"]
                    ?: baseNode
            parent.children.add(tempNode)
        }
    }
}

open class LevelIndex(
    var value: String? = null,
    var children: MutableList<LevelIndex> = arrayListOf()
)

class LevelOne : LevelIndex() {
    var defaultValue: Boolean? = false
}

class LevelTwo : LevelIndex() {
    var defaultValue: Boolean? = false
}

class LevelThree : LevelIndex() {
    var defaultValue: Boolean = false
}

UPDATE

I want index value by root level because, I have one id, I want to match that combination with that id, if that value is present then I am storing that value b true, and need to find that index value.

                                 Node
                     |                 |                 |
Level A ->           1                 2                 3
index value->        0                 1                 2
default value->     false             true             false
                 |       |          |      |          |     |
                 |       |          |      |          |     |
Leve B->         4       5          6      7          8     9
index value->    0       1          2      3          4     5
default value->false   false       true   false     false  false
....// more level

So, Level A I'll get index 1.

For Level B I'll get index 2

CodePudding user response:

I'd create a list to put the nodes at each level in order. You can recursively collect them from your tree.

val nodesByLevel = List(3) { mutableListOf<LevelIndex>() }

fun collectNodes(parent: LevelIndex) {
    for (child in parent.children) {
        val listIndex = when (child) {
            is LevelOne -> 0
            is LevelTwo -> 1
            is LevelThree -> 2
            // I made LevelIndex a sealed class. Otherwise you would need an else branch here.
        }
        nodesByLevel[listIndex]  = child
        collectNodes(child)
    }
}

collectNodes(baseNode)

Now nodesByLevel contains three lists containing all the nodes in each layer in order.

If you just need the String values, you could change that mutableList to use a String type and use = child.value ?: "" instead, although I would make value non-nullable (so you don't need ?: ""), because what use is a node with no value?

Edit I would move defaultValue up into the parent class so you don't have to cast the nodes to be able to read it. And I'm going to treat is as non-nullable.

sealed class LevelIndex(
    var value: String = "",
    val children: MutableList<LevelIndex> = arrayListOf()
    var isDefault: Boolean = false
)

Then if you want to do something with the items based on their indices:

for ((layerNumber, layerList) in nodesByLevel.withIndex()) {
    for((nodeIndexInLayer, node) in layerList) {
        val selectedIndexForThisLayer = TODO() //with layerNumber
        node.isDefault = nodeIndexInLayer == selectedIndexForThisLayer
    }
}
  • Related