我正在寻找一个算法来获取一个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。
我所有的尝试都试图反复这样做。
效率并不重要,因为它不会经常运行。
希望我的问题很明确。感谢您
答案 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)+1
,lvl
你的树的水平。请参阅下面的函数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 */