Skip to content

Instantly share code, notes, and snippets.

@ayusinghi96
Last active October 31, 2020 17:15
Show Gist options
  • Save ayusinghi96/a212ece0164ebeea70b9f6dc6195d09f to your computer and use it in GitHub Desktop.
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.
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