Skip to content

Swift implementation #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions Swift/tree.playground/Contents.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import Foundation


class Node<T>: CustomStringConvertible where T: CustomStringConvertible, T: Comparable {
Copy link

@GYFK GYFK Jun 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not the preferred code style and is wrong in the means of your task. It is mainly used when you have several Generic and try to constrain them like:

class Nodes<A, B, C> where A: Comparable, B: Equatable, C: CustomStringConvertible {
	
}

It may be better to use &here.

class Node<T>: CustomStringConvertible where T: CustomStringConvertible & Comparable {

because you use only one Generic and only a few protocols. When you have more protocols It is better to use a typealias

typealias NodeRelatedProtocol = CustomStringConvertible & Comparable & Equatable

class Node<T>: CustomStringConvertible where T: NodeRelatedProtocol {

Yet for this task you should use extensions combined with the element-based behavior.

public class Node<T> {

	public typealias Element = T
	public let value: Element
	
	public init(with value: Element) {
		self.value = value
	}
}

public extension Node where Node.Element: Equatable {
	
	func nodeValueEqualTo(valueOf aNode: Node) -> Bool {
		return self.value == aNode.value
	}
}


var value: T?
weak var parentNode: Node?
var subNodes = [Node]()
var subNodesCount: Int {
return subNodes.count
}
var isEmpty: Bool {
return subNodes.isEmpty
}

init() { }

init(value: T) {
self.value = value
}

func addChild(node child: Node) {
child.parentNode = self
subNodes.append(child)
}

func delete() {
parentNode!.subNodes = parentNode!.subNodes.filter({ $0 !== self })
Copy link

@GYFK GYFK Jun 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very bad idea combined with using the value of parentNode as a Node? with the write access from outside the class.

If the user tries for some reason doing the following

let tree = Tree<Int>()
tree.root.value = 99
tree.root.parentNode = nil
tree.root.delete()

The result is predictable.

}

var description: String {
var nodeValueStringRepresentation: String = ""
if let value = value {
nodeValueStringRepresentation = String(describing: value)
}

let subNodesStringRepresentation: String = subNodes.map({ $0.description }).reduce("", { (result, string) -> String in
return result + " " + string
})
return nodeValueStringRepresentation + ":{" + subNodesStringRepresentation + " }"
}

func containsNode(withValue nodeValue: T) -> Bool {
if !subNodes.isEmpty {
return subNodes.map({ $0.containsNode(withValue: nodeValue) }).reduce(false, { $0 || $1 })
} else {
return nodeValue == value
}
}

}

class Tree<T>: CustomStringConvertible where T: CustomStringConvertible, T: Comparable {

let root = Node<T>()

var description: String {
return "Tree: " + root.description
}

func containsNode(withValue value: T) -> Bool {
return root.containsNode(withValue: value)
}

}


// Initializing tree
let tree = Tree<Int>()
let root = tree.root
// Setting root value (this step is optional)
root.value = 999

// Initializing nodes and adding child nodes
let myNode = Node(value: 1)
myNode.addChild(node: Node(value: 10))
myNode.addChild(node: Node(value: 20))
myNode.addChild(node: Node(value: 30))

root.addChild(node: myNode)
root.addChild(node: Node(value: 2))
root.addChild(node: Node(value: 3))
root.addChild(node: Node(value: 4))

// Printing tree
print(tree)

// Geting and printing subtree
if let subtree = root.subNodes.first {
print(subtree)
}

// Checking if subtree have a tree with this value
print(tree.containsNode(withValue: 2))
print(tree.containsNode(withValue: 7))


// Node deletion
myNode.delete()
print(tree)
4 changes: 4 additions & 0 deletions Swift/tree.playground/contents.xcplayground
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='macos'>
<timeline fileName='timeline.xctimeline'/>
</playground>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.