Last active
October 31, 2020 17:15
-
-
Save ayusinghi96/a212ece0164ebeea70b9f6dc6195d09f to your computer and use it in GitHub Desktop.
A swift implementation to create a basic Binary tree and perform inOrder, preOrder and postOrder traversals on the tree.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
// MARK: - A node | |
final class Node { | |
/// Value of the node | |
var value: Int | |
/// Left child node | |
var left: Node? | |
/// Right child node | |
var right: Node? | |
private init(value: Int, left: Node?, right: Node?) | |
{ | |
self.value = value | |
self.left = left | |
self.right = right | |
} | |
convenience init(value: Int) { | |
self.init(value: value, left: nil, right: nil) | |
} | |
public func addChild(left: Node) { | |
self.left = left | |
} | |
public func addChild(right: Node) { | |
self.right = right | |
} | |
} | |
// MARK: - Equatable conformance | |
extension Node: Equatable { | |
static func == (lhs: Node, rhs: Node) -> Bool { | |
return lhs.value == rhs.value | |
} | |
} | |
// MARK: - A node builder | |
public class NodeBuilder { | |
/// List of node values in a sequence starting from `root` going `left -> right` | |
private static let values = [1,2,3,4,5,6,7,8,9] | |
/// List of created nodes. | |
var nodes: [Node] = [] | |
init() { } | |
/// | |
/// Create nodes from a list of node values. | |
/// | |
func createNodes() { | |
for value in NodeBuilder.values { | |
self.nodes.append(.init(value: value)) | |
} | |
} | |
} | |
// MARK: - A tree | |
final class Tree { | |
/// A node builder | |
private var nodeBuilder: NodeBuilder | |
/// A list of nodes from the nodes builder. | |
private var nodes: [Node] { | |
return self.nodeBuilder.nodes | |
} | |
/// Root of the tree. | |
var root: Node { | |
return self.nodes[0] | |
} | |
init() { | |
self.nodeBuilder = NodeBuilder() | |
self.createTree() | |
} | |
/// | |
/// Create a list of nodes. | |
/// | |
private func createNodes() { | |
self.nodeBuilder.createNodes() | |
} | |
/// | |
/// Attach children to a node if they `exist`. | |
/// | |
/// - Parameters: | |
/// - node: A node to attach children to. | |
/// | |
private func attachChildren(to node: Node) { | |
guard let index = self.nodeBuilder.nodes.firstIndex(of: node) else { return } | |
let newIndex = index + 1 | |
let leftIndex = 2 * newIndex | |
let rightIndex = (2 * newIndex) + 1 | |
if leftIndex - 1 >= self.nodeBuilder.nodes.count | |
{ | |
return | |
} | |
let leftNode = self.nodeBuilder.nodes[leftIndex - 1] | |
node.addChild(left: leftNode) | |
self.attachChildren(to: leftNode) | |
if rightIndex - 1 >= self.nodeBuilder.nodes.count | |
{ | |
return | |
} | |
let rightNode = self.nodeBuilder.nodes[rightIndex - 1] | |
node.addChild(right: rightNode) | |
self.attachChildren(to: rightNode) | |
} | |
/// | |
/// Create a tree by attaching children to nodes. | |
/// | |
private func createTree() { | |
self.createNodes() | |
let root = self.nodeBuilder.nodes[0] | |
self.attachChildren(to: root) | |
} | |
/// | |
/// Print the tree | |
/// | |
func printTree() | |
{ | |
for node in self.nodes { | |
print("value: \(node.value)") | |
print("leftChild: \(String(describing: node.left?.value))") | |
print("rightChild: \(String(describing: node.right?.value))") | |
} | |
} | |
/// | |
/// Do an in-order traversal. | |
/// | |
func inorderTraversal(from node: Node?) { | |
if node == nil { return } | |
inorderTraversal(from: node?.left) | |
print(String(node?.value ?? 0), terminator: " ") | |
inorderTraversal(from: node?.right) | |
} | |
/// | |
/// Do a post-order traversal. | |
/// | |
func postorderTraversal(from node: Node?) { | |
if node == nil { return } | |
postorderTraversal(from: node?.left) | |
postorderTraversal(from: node?.right) | |
print(String(node?.value ?? 0), terminator: " ") | |
} | |
/// | |
/// Do a pre-order traversal. | |
/// | |
func preorderTraversal(from node: Node?) { | |
if node == nil { return } | |
print(String(node?.value ?? 0), terminator: " ") | |
preorderTraversal(from: node?.left) | |
preorderTraversal(from: node?.right) | |
} | |
} | |
// MARK: - Driving code | |
let tree = Tree() | |
tree.printTree() | |
print("Preorder") | |
tree.preorderTraversal(from: tree.root) | |
print("\nInorder") | |
tree.inorderTraversal(from: tree.root) | |
print("\nPostorder") | |
tree.postorderTraversal(from: tree.root) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment