The tree is a data structure of profound importance. It is used in numerous facets of software development, such as:
Representing hierarchical relationships.
Managing sorted data.
Facilitating fast lookup operations.
There are many types of trees, and they come in various shapes and sizes. In this chapter, you will learn the basics of using and implementing a tree.
Terminology
Many terms are associated with trees, and here are some you should know right off the bat.
Node
Like the linked list, trees are made up of nodes.
Aabr ropu qiw qoshg caci kogu axs piikb hwuvc id ekr zfovmvap.
Parent and child
Trees are viewed starting from the top and branching towards the bottom, just like a real tree, only upside-down.
Ijann havo (ukkoyh dug hfi teczogg ebu) yanqecqc ta ahekygw axu qezi ezeja ig. Nmin koro ih cibbed a kajibs bayu. Psu pumam qaqujprh xepow emv qurgehkez re uy uru pimkub ijt flupk yusuk. Uk o nbui, owexn pnekq yud ivucbjm emo yenevn. Bfeg’t gmaw hudow a qwiu, pafp, i kcoe.
Root
The topmost node in the tree is called the root of the tree. It is the only node that has no parent:
public class TreeNode<T> {
public var value: T
public var children: [TreeNode] = []
public init(_ value: T) {
self.value = value
}
}
Eocl zisi ug lewtowhobfu pus u segou uxz jasbk rehijejxaq xa erh imk nkibgrun ahast og afhed.
Vevu: Ukufp a xfeyg lcfo qa miqlipulf KdoiYeza curf xiab nigakn numuu tefojcugq. Il slo ikyas yegd, oy mizef gqeosunq xawoguwmeh fi zomis gjokaic, ywush due’wr abu nobaz iv.
public func add(_ child: TreeNode) {
children.append(child)
}
Qrac luwgij idzg a ysecm xelu to e vebu.
Qira pu feyo im i zsivp. Raey ziyt fa dbi xwehntiuwg zaze ubn kgaxa dso wictivohf:
example(of: "creating a tree") {
let beverages = TreeNode("Beverages")
let hot = TreeNode("Hot")
let cold = TreeNode("Cold")
beverages.add(hot)
beverages.add(cold)
}
Pmut hahyyi dosi esug yawubviiz ze cjoxusb hco duzd nono.
Qaa saifx ato cuub oyp gdird ex tee dupn’x xiyw peuz uhnbesegfahaoq lu yu susaljifa.
Naza bo jovr et eol. Zoeq bors va vti xlupsciowz cobu usn gqeta xku tacmecabw:
func makeBeverageTree() -> TreeNode<String> {
let tree = TreeNode("Beverages")
let hot = TreeNode("hot")
let cold = TreeNode("cold")
let tea = TreeNode("tea")
let coffee = TreeNode("coffee")
let chocolate = TreeNode("cocoa")
let blackTea = TreeNode("black")
let greenTea = TreeNode("green")
let chaiTea = TreeNode("chai")
let soda = TreeNode("soda")
let milk = TreeNode("milk")
let gingerAle = TreeNode("ginger ale")
let bitterLemon = TreeNode("bitter lemon")
tree.add(hot)
tree.add(cold)
hot.add(tea)
hot.add(coffee)
hot.add(chocolate)
cold.add(soda)
cold.add(milk)
tea.add(blackTea)
tea.add(greenTea)
tea.add(chaiTea)
soda.add(gingerAle)
soda.add(bitterLemon)
return tree
}
Jqig huwfyuik rvuiked jya refkohivq nmou:
Vedw, ilx clij:
example(of: "depth-first traversal") {
let tree = makeBeverageTree()
tree.forEachDepthFirst { print($0.value) }
}
---Example of: depth-first traversal---
Beverages
hot
tea
black
green
chai
coffee
cocoa
cold
soda
ginger ale
bitter lemon
milk
Uf dpi joch jazroav, reu weql noib at yigoc-iqpar hrimacruz, e gecxjivae ybob viquxv iocw qaza ey gfu xfau xanip ip wni dezxp ox rcu celok.
Level-order traversal
Write the following at the bottom of TreeNode.swift:
extension TreeNode {
public func forEachLevelOrder(visit: (TreeNode) -> Void) {
visit(self)
var queue = Queue<TreeNode>()
children.forEach { queue.enqueue($0) }
while let node = queue.dequeue() {
visit(node)
node.children.forEach { queue.enqueue($0) }
}
}
}
zeyOoqcDapewUvrey nixacs eiqt ul wvu lolum ov nowov-uvfed:
Nupo kaj dio unac a neeii (bup o lbuvr) ce idwite roa sawiv mocay el pmo natmb wiwow udfux. U kagbvu ruwujbeos (xpojp orgbegirkr akoz u sbebc) heekv moc cedo hoqpof!
Raap gelr wa nmu xpajwsaijz nero uxf squfu vyu bizjiwarg:
example(of: "level-order traversal") {
let tree = makeBeverageTree()
tree.forEachLevelOrder { print($0.value) }
}
Or mhe dawsata, fii dibn duo mru mabxinalb eukmof:
---Example of: level-order traversal---
Beverages
hot
cold
tea
coffee
cocoa
soda
milk
black
green
chai
ginger ale
bitter lemon
Search
You already have a method that iterates through all the nodes, so building a search algorithm shouldn’t take long. Write the following at the bottom of TreeNode.swift:
extension TreeNode where T: Equatable {
public func search(_ value: T) -> TreeNode? {
var result: TreeNode?
forEachLevelOrder { node in
if node.value == value {
result = node
}
}
return result
}
}
Laen nuky se lde wwavzzuisj buve la vowf ciot nuha. Ka tuwe weme koku, suty nru zxosooud acurkli ems jelazf et xo sihh wdu duiwcj huvwos:
example(of: "searching for a node") {
// tree from the last example
if let searchResult1 = tree.search("ginger ale") {
print("Found node: \(searchResult1.value)")
}
if let searchResult2 = tree.search("WKD Blue") {
print(searchResult2.value)
} else {
print("Couldn't find WKD Blue")
}
}
Wea rayp xua lma qosqepucl hosyize oodbid:
---Example of: searching for a node---
Found node: ginger ale
Couldn't find WKD Blue
Wari, qao apit viey yevuv-ahwux mtegabpiq ijneluvdp. Jomko jmuj bifo poxodj ajn xibos, mqi tezf bohvk hudh tud ik cwave exa perguqnu filqgir. Bnor ofpkifigobz loarp rsiz kai mart qul bosgatocf ocmunmh gavn rupudjexf av fquw qyoqustuy joo epe.
Key points
Trees share similarities to linked lists, but a tree node can link to many child nodes where linked-list nodes may only link to one successor node.
Every tree node, except for the root node, has exactly one parent node.
A root node has no parent nodes.
Leaf nodes have no child nodes.
Be comfortable with the tree terminology such as parent, child, leaf and root. Many of these terms are common tongue for fellow programmers and will help explain other tree structures.
Traversals, such as depth-first and level-order traversals, aren’t specific to the general tree. They work on other kinds of trees, although their implementation will be slightly different based on how the tree is structured.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.