diff --git a/DIRECTORY.md b/DIRECTORY.md index e1bce5e..e469005 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -34,6 +34,8 @@ * [Shunting Yard](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/parsing/shunting_yard/shunting_yard.swift) ## Data Structures + * Doubly Linked List + * [Doublylinkedlist](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/doubly_linked_list/DoublyLinkedList.swift) * Heap * [Heap](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/heap/heap.swift) * Linked List @@ -46,6 +48,10 @@ * [Union Find](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/union_find/union_find.swift) ## Graph + * Bfs + * [Bfs](https://github.com/TheAlgorithms/Swift/blob/master/graph/BFS/BFS.swift) + * Dfs + * [Dfs](https://github.com/TheAlgorithms/Swift/blob/master/graph/DFS/DFS.swift) * Spanning Tree * [Kruskal](https://github.com/TheAlgorithms/Swift/blob/master/graph/spanning_tree/kruskal.swift) diff --git a/data_structures/doubly_linked_list/DoublyLinkedList.swift b/data_structures/doubly_linked_list/DoublyLinkedList.swift new file mode 100644 index 0000000..ca9f614 --- /dev/null +++ b/data_structures/doubly_linked_list/DoublyLinkedList.swift @@ -0,0 +1,194 @@ +import Foundation + +public class Node { + public var value: Value? + public var next: Node? + public var prev: Node? + + public init(value: Value? = nil, next: Node? = nil, prev: Node? = nil) { + self.value = value + self.next = next + self.prev = prev + } +} + +extension Node: CustomStringConvertible { + public var description: String { + guard let next: Node = self.next else { + return "\(String(describing: value))" + } + return "\(String(describing: value)) <-> \(String(describing: next)) " + } +} + +public struct DoublyLinkedList { + + public var head: Node? + public var tail: Node? + public var count: Int = 0 + + public var isEmpty: Bool { + return head == nil + } + + public mutating func push(_ value: Value) { + let new: Node = Node(value: value, next: head) + if head != nil { head!.prev = new } + head = new + if tail == nil { tail = head } + count += 1 + } + + public mutating func append(_ value: Value) { + guard !isEmpty else { + push(value) + return + } + tail!.next = Node(value: value, prev: tail) + tail = tail!.next + count += 1 + } + + @discardableResult + public mutating func insert(_ value: Value, + after node: Node) -> Node { + guard tail !== node else { + append(value) + return tail! + } + var new: Node = Node(value: value, next: node.next, prev: node) + node.next?.prev = new + node.next = new + count += 1 + return node.next! + } + + @discardableResult + public mutating func insert(_ value: Value, + before node: Node) -> Node { + guard head !== node else { + push(value) + return head! + } + var new: Node = Node(value: value, next: node, prev: node.prev) + node.prev?.next = new + node.prev = new + count += 1 + return node.prev! + } + + public func node(at index: Int) -> Node? { + guard index > -1 || index < count else { return nil } + + let startFromTail: Bool = index > count / 2 + var currentNode: Node? = startFromTail ? tail : head + var currentIndex: Int = startFromTail ? count - 1 : 0 + var change: Int = startFromTail ? -1 : 1 + + while currentNode != nil { + if currentIndex == index { break } + currentNode = startFromTail ? currentNode!.prev : currentNode!.next + currentIndex += change + } + + return currentNode + } + + @discardableResult + public mutating func pop() -> Value? { + defer { + head = head?.next + count -= 1 + if isEmpty { + tail = nil + } else { + head!.prev = nil + } + } + return head?.value + } + + @discardableResult + public mutating func removeLast() -> Value? { + defer { + tail = tail?.prev + count -= 1 + if isEmpty { + head = nil + } else { + tail!.next = nil + } + } + return tail?.value + } + + @discardableResult + public mutating func remove(after node: Node) -> Value? { + defer { + if node.next != nil { + count -= 1 + } + if node.next === tail { + tail = node + } + if let next2node: Node = node.next?.next { + next2node.prev = node + } + node.next = node.next?.next + } + return node.next?.value + } + + @discardableResult + public mutating func remove(before node: Node) -> Value? { + defer { + if node.prev != nil { + count -= 1 + } + if node.prev === head { + head = node + } + if let prev2node: Node = node.prev?.prev { + prev2node.next = node + } + node.prev = node.prev?.prev + } + return node.prev?.value + } +} + +extension DoublyLinkedList: CustomStringConvertible { + public var description: String { + guard let head: Node = self.head else { + return "Empty list" + } + return String(describing: head) + } +} + +// Here are testing scenarios to run in a Swift playground + +/* +var list = DoublyLinkedList() + +list.push(4) +list.push(2) +list.push(1) + +list.append(6) + +var n = list.node(at: 2) + +list.insert(5, after: n!) +list.insert(3, before: n!) + +print(list) + +print(list.pop()!) +print(list.removeLast()!) + +print(list.remove(after: n!)!) +print(list.remove(before: n!)!) + +print(list.count) +*/ diff --git a/graph/BFS/BFS.swift b/graph/BFS/BFS.swift new file mode 100644 index 0000000..24d99ce --- /dev/null +++ b/graph/BFS/BFS.swift @@ -0,0 +1,75 @@ +// MARK: - Basic requirement +struct Edge { + let from: Int + let to: Int +} + +public class Node { + var val: Int + var neighbors: [Int] + public init(_ val: Int) { + self.val = val + self.neighbors = [] + } +} + +// MARK: - BFS implementation +func testBFS(edges: [Edge]) { + + var graph = [Int: Node]() + for edge in edges { + graph[edge.from] = Node(edge.from) + graph[edge.to] = Node(edge.to) + } + for edge in edges { + graph[edge.from]?.neighbors.append(edge.to) + graph[edge.to]?.neighbors.append(edge.from) + } + var visited: [Bool] = Array(repeating: false, count: graph.count + 1) + var nodesOfCurrentLevel: [Int] = [] + + for node in 1...graph.count { + if visited[node] == false { + nodesOfCurrentLevel.append(node) + while(nodesOfCurrentLevel.isEmpty == false) { + var nodesOfNextLevel: [Int] = [] + let sizeOfQueue = nodesOfCurrentLevel.count + for index in 0..