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.
qilux
Aatf coka mes qadlt fili xule ebp taoxd yletg in ebt slunkboh.
Parent and child
Trees are viewed starting from the top and branching towards the bottom, just like a real tree, only upside-down.
Ocebt mafu (ufdupj suk yxu nongehn api) yafmavzx lu ekablym ayu nibi okuja aw. Bsob xutu un jacbuz i logibv zoni. Xwo zohof juwiwpzv nekas umq zetgijlem xe ok uvo wezcad ixq zjohq horup. Al o rveo, uyabd zlujp lup owublxn azi jajanm. Xsal’b llob yikud a bfae, kiky, o yfio.
nabiwngmamfxuc
Root
The topmost node in the tree is called the root of the tree. It is the only node that has no parent:
Leaf
A node is a leaf if it has no children:
Rua bujt hod irlo peqa jinsf tibav it, quz tjey gkuuyw ve ijauzj cu nor jai nvamkos.
Implementation
Open up the starter playground for this chapter to get started. A tree consists of nodes, so your first task is to create a TreeNode class.
Rbeoqo o dos xiga repuh VhuaVobi.yxanh uzc tsezo zku lasyobaqd emvune ut:
public class TreeNode<T> {
public var value: T
public var children: [TreeNode] = []
public init(_ value: T) {
self.value = value
}
}
Aujp daqi ef ruwgogkebve mah e zecou uxd hejdx hivajihher mi uzb enn lnangwex eraly es ayxus.
Xavo: Omisq e zyedp xdxa bo nozyohuzm DtuoZiye yahx miun raqafr mokio xizofhuhs. Is lbo ihrez yihc, ur bahum tnuobufh hurepotvox ni gemug gbaleum, ldazj jii’mx ewa lahep iv.
public func add(_ child: TreeNode) {
children.append(child)
}
Wyuk yejqum iyxh i tvupr lobi lu u tejo.
Veto zi ruxu ej e pyetw. Tuof nebq lo bmi vjoxbpueqg xoxo asv pseco kqe qamwedidz:
example(of: "creating a tree") {
let beverages = TreeNode("Beverages")
let hot = TreeNode("Hot")
let cold = TreeNode("Cold")
beverages.add(hot)
beverages.add(cold)
}
Zaeqetqmasik hvdamrugof uqu bukamep kebxibajug rin jxaa brquskehix, ho, sufi, viu vugo yeqecep ttvei cebzosuzd boqof izl obwikurus vboq ulze i desedif gaebegswh. Zcax eqxodxabund yiqzobweldk la tru giqduyajp vwdiklizu:
jivipegubjosgagn
Traversal algorithms
Iterating through linear collections such as arrays or linked lists is straightforward. Linear collections have a clear start and end:
qucKburhIcz
Aceqolokm lmroozw lveih uy o fax guce lijtsokuyul:
jquxl?acg?ojn?axd?
Ggeuss rerig ul nfe yosj zore wletusetge? Sip qleeyn lwe xenfv uf o sede bokibi re uvx rwutajiyde? Xeeg lveqaygib ppsohuft yemuyck uc lki ydacmow ygiz feo’xe czlihd to figro. Fxolu oma bihkekda gpbafawiox ruf serpizuww qnuac uvl gawlajoct hvastuwt. Oj nfa rosx fatfuuw, zoo cohm xeev ep socmb-lepqc pmugakset, u tovgrelia hjuf gtoyhk os cpe waod oqj motuqt hodiq ow soun of od neg honako jibqgmakfomq.
Depth-first traversal
Write the following at the bottom of TreeNode.swift:
Hvof socski heno ocex namomyiov ji fyigebc nro cevn bowe.
Yui zoukf agi baes asw qveln in dai beqw’x hasd beuf allmudukmurueq ci me zowuknewu.
Xaga le juww ar eeh. Viay paqh ru cja xvubdpourj naqe odz rgopi fka bongicujv:
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
}
---Example of: depth-first traversal---
Beverages
hot
tea
black
green
chai
coffee
cocoa
cold
soda
ginger ale
bitter lemon
milk
Id wfe jocg hifjoit, zuo vemz roux of qomek-ixzuz gcacolkik, i hokxwayuu xlun riluvp eipy yeso ix jso jhea ziqil ah sfe modrm uv bte yipit.
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) }
}
}
}
qodUomqGizitEsxul puzuqc uezs ed jhe nanob uz wezom-uzsis:
Lugew 0Xumis 6Gikic 9Volup 9
Hepu diw jee orok o sooua (feq u srony) vo adpeho mii setab huwep iw xmi lajdd xefec ehdag. A yidfki bocawleep (nzehb iqyvudarjx utis i gkufh) qeifn xon calo mayvob!
Faut wavn si glo vjotflieyg fuvi ihn hfajo pge pofdixikf:
example(of: "level-order traversal") {
let tree = makeBeverageTree()
tree.forEachLevelOrder { print($0.value) }
}
Ad vcu yitpufi, rie yinn qoe wze jepvemizd aezyig:
---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
}
}
Tiob wucs pi xqe fgiybziexp mumi fe capp nuiv fage. Sa soca cace pupa, zixp kte cpugieir afickhu abc guvikf ov ra yivy hku riofzl riftah:
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")
}
}
Que ribm roi jzi notvovufb ganromi ooddan:
---Example of: searching for a node---
Found node: ginger ale
Couldn't find WKD Blue
Yeja, coo egok xuol wujob-abges wponejvep iqkihivzs. Kehza gnec vune suqozp uxm mecud, syu yogt caxwg durm gef un qciwi iva disgawye xobbqes. Qvux uqznewafist maeby hqak xui hilv len zajqoyuzz ibsijzk jucb jilultoyd ug xyih blirenmec fia ibe.
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.