树级别 - 向量中元素的遍历遍历

时间:2016-01-20 20:31:33

标签: algorithm tree

我正在寻找一个算法来获取一个x值列表,然后从中间开始循环,然后是左边的中间,然后是右边的中间,然后是左边中间的中间...就像一棵树。

我不认为递归会起作用,因为它会在到达另一侧之前完全遍历一侧。我需要均匀解析。

Pretend this is a list of 50 numbers:
.................................................. (50)

Need to find the 25th element first

........................1......................... (lvl1)

Then the 12th, then 38th
...........2.........................3............ (lvl2)

Then the 6,18   31,44
.....4...........5.............6...........7...... (lvl3)

Then the 3,9,15,21   28,34,41,48
..8.....9.....a......b.....c.......d.....e.....f.. (lvl4)

等......直到遍历了所有值。所以当lvl4被击中时,我已经按顺序看到了1,2,3,4,5,6,7,8,9,a,b,c,d,e,f。

我所有的尝试都试图反复这样做。

效率并不重要,因为它不会经常运行。

希望我的问题很明确。感谢您

2 个答案:

答案 0 :(得分:1)

你可以通过queue data structure和一些数学来解决这个问题。

首先推入元组(0,25,49)。这表明这是位置25处的节点,分割范围0-49。所以队列应该是这样的:

[(0,25,49)]

现在在每个点上,删除队列的前面,在索引处打印元素,然后推入后代。那么,例如,当你弹出(0,25,49)时,如何跟踪后代?左后卫是0-24范围的中间位置,所以你可以推进(0,12,24)。右后卫是26-49范围的中间位置,所以你会推进(26,38,49)。所以队列应该是这样的:

[(0,13,23),(26,38,49)]。

等等。

答案 1 :(得分:0)

(后面的解决方案是用Swift编写的,但我希望你能按照它并翻译成你喜欢的语言,以备你使用它时)

我们可以很容易地提出一个解决方案,该解决方案适用于特殊情况,其中您的数组值描述完整(/正确)二叉树,即numElements = 2^(lvl-1)+1lvl你的树的水平。请参阅下面的函数printFullBinaryTree(...)

现在,我们还可以轻松地将任何数组扩展为描述完整二叉树的数组,请参阅expandToFullBinary。 “

通过组合这两种方法,我们有一个任何大小的输入数组的通用方法。

将任何数组展开为描述完整二叉树的数组:

/* given 'arr', returns array expanded to full binary tree (if necessary) */
func expandToFullBinary(arr: [String], expandByCharacter: String = "*") -> [String] {

    let binLength = Int(pow(2.0,Double(Int(log2(Double(arr.count)))+1)))-1
    if arr.count == binLength {
        return arr
    }
    else {
        let diffLength = binLength - arr.count
        var arrExpanded = [String](count: binLength, repeatedValue: expandByCharacter)

        var j = 0
        for i in 0 ..< arr.count {
            if i < (arr.count - diffLength) {
                arrExpanded[i] = arr[i]
            }
            else {
                arrExpanded[i+j] = arr[i]
                j = j+1
            }
        }

        return arrExpanded
    }
}

根据您的问题规范将打印数组(描述完整的二进制树)作为二叉树:

/* assumes 'arr' describes a full binary tree */
func printFullBinaryTree(arr: [String]) {

    var posVectorA : [Int] = [arr.count/2]
    var posVectorB : [Int]
    var splitSize : Int = arr.count/2

    var elemCount = 0

    if arr.count < 2 {
        print("\(arr.first ?? "")")
    }
    else {
        while elemCount < arr.count {
            posVectorB = []
            splitSize = splitSize/2
            for i in posVectorA {

                if elemCount == arr.count {
                    print("noo")
                    break
                }

                print(arr[i], terminator: " ")
                elemCount = elemCount + 1

                posVectorB.append(i-splitSize-1)
                posVectorB.append(i+splitSize+1)
            }
            print("")
            posVectorA = posVectorB
        }
    }
}

描述完整二叉树的向量示例以及描述非完整二叉树的向量示例:

/* Example */
var arrFullBinary : [String] = ["8", "4", "9", "2", "a", "5", "b", "1", "c", "6", "d", "3", "e", "7", "f"]

var arrNonFullBinary : [String] = ["g", "8", "h", "4", "i", "9", "j", "2", "a", "5", "b", "1", "c", "6", "d", "3", "e", "7", "f"]

printFullBinaryTree(expandToFullBinary(arrFullBinary, expandByCharacter: ""))
/* 1
   2 3
   4 5 6 7
   8 9 a b c d e f    */

printFullBinaryTree(expandToFullBinary(arrNonFullBinary, expandByCharacter: ""))
/* 1
   2 3
   4 5 6 7
   8 9 a b c d e f
   g h i j            */