├── .gitignore ├── README.md └── learn_data_structure.playground ├── Contents.swift ├── Pages ├── Doubly Linked List.xcplaygroundpage │ └── Contents.swift ├── Queue (Ring Buffer).xcplaygroundpage │ └── Contents.swift ├── Queue (Two Stack).xcplaygroundpage │ └── Contents.swift ├── Queue (With Array).xcplaygroundpage │ └── Contents.swift ├── Queue (With Linked List).xcplaygroundpage │ └── Contents.swift ├── Singly LInked List.xcplaygroundpage │ └── Contents.swift ├── Stack (Array).xcplaygroundpage │ └── Contents.swift └── Stack (Without Array).xcplaygroundpage │ └── Contents.swift └── contents.xcplayground /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structure in Swift (iOS) 2 | 3 | To learn about the Data Structure and Algorithms in Swift language. 4 | 5 | * Singly Linked List (Insertion & Deletion) 6 | * Stack (Push & Pop) 7 | * Doubly Linked List (Insertion & Deletion) 8 | 9 | -------------------------------------------------------------------------------- /learn_data_structure.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | var str = "Hello, playground" 4 | -------------------------------------------------------------------------------- /learn_data_structure.playground/Pages/Doubly Linked List.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | 2 | // ***************** Doubly Linked List ********************* 3 | 4 | class Node: CustomStringConvertible, Equatable { 5 | 6 | var value: T 7 | var next: Node? 8 | weak var prev: Node? 9 | 10 | // required conforms to CustomStringConvertible 11 | var description: String { 12 | guard let next = next else { return "\(value)" } 13 | return "\(value) -> " + String(describing: next) 14 | } 15 | 16 | init(_ value: T, prev: Node?, next: Node?) { 17 | self.value = value 18 | self.prev = prev 19 | self.next = next 20 | } 21 | 22 | // required conforms to Equatable 23 | static func ==(lhs: Node, rhs: Node) -> Bool { 24 | return lhs.next == rhs.next 25 | } 26 | } 27 | 28 | 29 | class DoublyLinkedList: CustomStringConvertible { 30 | 31 | var head: Node? = nil 32 | var tail: Node? = nil 33 | 34 | var isEmpty: Bool { 35 | head == nil 36 | } 37 | 38 | // required conforms to CustomStringConvertible 39 | var description: String { 40 | guard let head = head else { return "Empty List !!!" } 41 | return String(describing: head) 42 | } 43 | 44 | init() { 45 | head = nil 46 | tail = head 47 | } 48 | 49 | func deleteAll() { 50 | head = nil 51 | tail = nil 52 | } 53 | } 54 | 55 | 56 | // common operations 57 | extension DoublyLinkedList { 58 | 59 | var first: Node? { 60 | head 61 | } 62 | 63 | var last: Node? { 64 | tail 65 | } 66 | 67 | // to access a node using subscript opetion i.e. [index] 68 | subscript(index: Int) -> Node? { 69 | node(at: index) 70 | } 71 | 72 | // get all the values in forward direction 73 | var forwardValues: [T]? { 74 | if isEmpty { return nil } 75 | var values: [T] = [] 76 | var currentNode = head 77 | while currentNode != nil { 78 | values.append(currentNode!.value) 79 | currentNode = currentNode?.next 80 | } 81 | return values 82 | } 83 | 84 | // get all the values in backward direction 85 | var backwardValues: [T]? { 86 | if let tailNode = tail { 87 | var values: [T] = [] 88 | var previousNode = tailNode 89 | repeat { 90 | values.append(previousNode.value) 91 | if let previous = previousNode.prev { 92 | previousNode = previous 93 | } 94 | } while previousNode.prev != nil 95 | return values 96 | } 97 | return nil 98 | } 99 | 100 | // get a node from a specific position 101 | func node(at index: Int) -> Node? { 102 | 103 | // if list is empty then return nil 104 | if isEmpty { return nil } 105 | 106 | if index >= 0 { 107 | var currentNode = head 108 | var currentIndex = 0 109 | while currentNode != nil && currentIndex < index { 110 | currentNode = currentNode?.next 111 | currentIndex += 1 112 | } 113 | return currentNode 114 | } 115 | return nil 116 | } 117 | 118 | func length() -> Int { 119 | var currentNode = head 120 | var length = 0 121 | while currentNode != nil { 122 | length += 1 123 | currentNode = currentNode?.next 124 | } 125 | return length 126 | } 127 | } 128 | 129 | // insertion operations 130 | extension DoublyLinkedList { 131 | 132 | // insert a value at start 133 | func push(_ value: T) { 134 | if isEmpty { 135 | head = Node(value, prev: nil, next: nil) 136 | tail = head 137 | } else { 138 | let newNode = Node(value, prev: nil, next: head) 139 | head?.prev = newNode 140 | head = newNode 141 | } 142 | } 143 | 144 | // insert a value at end 145 | func append(_ value: T) { 146 | let newNode = Node(value, prev: nil, next: nil) 147 | if let tail = tail { 148 | newNode.prev = tail 149 | tail.next = newNode 150 | } else { 151 | head = newNode 152 | } 153 | tail = newNode 154 | } 155 | 156 | // insert a value after at given index 157 | func insert(after index: Int, value: T) -> Bool { 158 | if let node = node(at: index) { 159 | 160 | if node == tail { 161 | append(value) 162 | return true 163 | } 164 | 165 | let newNode = Node(value, prev: node, next: node.next) 166 | if let oldNextNode = node.next { 167 | node.next = newNode 168 | oldNextNode.prev = newNode 169 | return true 170 | } 171 | } 172 | return false 173 | } 174 | } 175 | 176 | // deletion operations 177 | extension DoublyLinkedList { 178 | 179 | // remove the first element of the list 180 | @discardableResult 181 | func pop() -> T? { 182 | defer { 183 | head = head?.next 184 | head?.prev = nil 185 | if isEmpty { 186 | tail = nil 187 | } 188 | } 189 | return head?.value 190 | } 191 | 192 | // remove the last element of the list 193 | @discardableResult 194 | func deleteLast() -> T? { 195 | guard var tailNode = tail, var headNode = head else { return nil } 196 | defer { 197 | if tailNode == headNode { 198 | tail = nil 199 | head = nil 200 | } else if let prev = tailNode.prev { 201 | tail = prev 202 | tail?.next = nil 203 | } 204 | } 205 | return tailNode.value 206 | } 207 | 208 | // remove an element from a specific position 209 | func remove(at index: Int) -> T? { 210 | if let node = self.node(at: index) { 211 | 212 | if node == head { 213 | return pop() 214 | } 215 | 216 | if node == tail { 217 | return deleteLast() 218 | } 219 | 220 | defer { 221 | let prev = node.prev 222 | let next = node.next 223 | prev?.next = node.next 224 | next?.prev = node.prev 225 | } 226 | return node.value 227 | } 228 | return nil 229 | } 230 | } 231 | 232 | 233 | var stringList = DoublyLinkedList() 234 | stringList.push("one") 235 | stringList.push("two") 236 | stringList.push("three") 237 | stringList.append("four") 238 | stringList.insert(after: 2, value: "five") 239 | stringList.pop() 240 | print(stringList) 241 | 242 | -------------------------------------------------------------------------------- /learn_data_structure.playground/Pages/Queue (Ring Buffer).xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | 2 | 3 | struct RingBufferQueue: CustomStringConvertible { 4 | 5 | private var elements: [T?] 6 | private var front = -1 7 | private var rear = -1 8 | 9 | init(count: Int) { 10 | elements = Array(repeating: nil, count: count) 11 | } 12 | 13 | var isEmpty: Bool { 14 | front == -1 && rear == -1 15 | } 16 | 17 | var isFull: Bool { 18 | ((rear + 1) % elements.count) == front 19 | } 20 | 21 | var description: String { 22 | if isEmpty { return "Queue is empty..." } 23 | return "---- Queue start ----\n" 24 | + elements.map({String(describing: "\($0)")}).joined(separator: " -> ") 25 | + "\n---- Queue End ----\n" 26 | } 27 | 28 | var peek: T? { 29 | if isEmpty { return nil } 30 | return elements[front] 31 | } 32 | } 33 | 34 | extension RingBufferQueue { 35 | 36 | // to enqueue an element 37 | mutating func enqueue(_ element: T) -> Bool { 38 | 39 | // if queue is empty 40 | if front == -1 && rear == -1 { 41 | front = 0 42 | rear = 0 43 | elements[rear] = element 44 | return true 45 | } 46 | 47 | if isFull { 48 | print("QUEUE IS FULL") 49 | return false 50 | } 51 | 52 | rear = (rear + 1) % elements.count 53 | elements[rear] = element 54 | return true 55 | } 56 | } 57 | 58 | extension RingBufferQueue { 59 | 60 | // to dequeue an element 61 | mutating func dequeue() -> T? { 62 | 63 | if isEmpty { 64 | print("QUEUE IS EMPTY") 65 | return nil 66 | } 67 | 68 | // if queue has only single element 69 | if front == rear { 70 | defer { 71 | elements[front] = nil 72 | front = -1 73 | rear = -1 74 | } 75 | return elements[front] 76 | } 77 | 78 | defer { 79 | elements[front] = nil 80 | front = (front + 1) % elements.count 81 | } 82 | return elements[front] 83 | } 84 | } 85 | 86 | 87 | 88 | 89 | var queue = RingBufferQueue(count: 10) 90 | queue.enqueue("1") 91 | queue.enqueue("2") 92 | queue.enqueue("3") 93 | queue.enqueue("4") 94 | queue.enqueue("5") 95 | if let dequeuedElement = queue.dequeue() { 96 | print("Dequeued Element: \(dequeuedElement)") 97 | } 98 | queue.enqueue("6") 99 | if let dequeuedElement = queue.dequeue() { 100 | print("Dequeued Element: \(dequeuedElement)") 101 | } 102 | if let dequeuedElement = queue.dequeue() { 103 | print("Dequeued Element: \(dequeuedElement)") 104 | } 105 | queue.enqueue("7") 106 | queue.enqueue("8") 107 | queue.enqueue("9") 108 | queue.dequeue() 109 | print(queue) 110 | print(queue.peek) 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /learn_data_structure.playground/Pages/Queue (Two Stack).xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | 2 | 3 | struct TwoStackQueue: CustomStringConvertible { 4 | 5 | private var leftStack: [T] = [] 6 | private var rightStack: [T] = [] 7 | 8 | var isEmpty: Bool { 9 | leftStack.isEmpty && rightStack.isEmpty 10 | } 11 | 12 | var peek: T? { 13 | leftStack.isEmpty ? rightStack.first : leftStack.last 14 | } 15 | 16 | var description: String { 17 | 18 | if isEmpty { 19 | return "Queue is empty..." 20 | } 21 | var allElements: [T] = [] 22 | if leftStack.isEmpty == false { 23 | allElements.append(contentsOf: leftStack.reversed()) 24 | } 25 | allElements.append(contentsOf: rightStack) 26 | 27 | return "---- Queue start ----\n" 28 | + allElements.map({"\($0)"}).joined(separator: " -> ") 29 | + "\n---- Queue End ----" 30 | } 31 | } 32 | 33 | extension TwoStackQueue { 34 | 35 | mutating func enqueue(_ element: T) { 36 | rightStack.append(element) 37 | } 38 | } 39 | 40 | extension TwoStackQueue { 41 | 42 | mutating func dequeue() -> T? { 43 | 44 | if isEmpty { 45 | return nil 46 | } 47 | 48 | if leftStack.isEmpty { 49 | leftStack = rightStack.reversed() 50 | rightStack.removeAll() 51 | } 52 | 53 | return leftStack.removeLast() 54 | } 55 | } 56 | 57 | var queue = TwoStackQueue() 58 | print(queue) 59 | queue.dequeue() 60 | queue.enqueue("1") 61 | queue.enqueue("2") 62 | queue.enqueue("3") 63 | queue.dequeue() 64 | queue.enqueue("4") 65 | queue.enqueue("5") 66 | queue.enqueue("6") 67 | queue.dequeue() 68 | print(queue.peek) 69 | print(queue) 70 | 71 | -------------------------------------------------------------------------------- /learn_data_structure.playground/Pages/Queue (With Array).xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | 2 | 3 | struct Queue: CustomStringConvertible { 4 | 5 | private var elements: [T] = [] 6 | public init() {} 7 | 8 | var isEmpty: Bool { 9 | elements.isEmpty 10 | } 11 | 12 | var peek: T? { 13 | elements.first 14 | } 15 | 16 | var description: String { 17 | if isEmpty { return "Queue is empty..." } 18 | return "---- Queue start ----\n" 19 | + elements.map({"\($0)"}).joined(separator: " -> ") 20 | + "\n---- Queue End ----" 21 | } 22 | 23 | mutating func enqueue(_ value: T) { 24 | elements.append(value) 25 | } 26 | 27 | mutating func dequeue() -> T? { 28 | isEmpty ? nil : elements.removeFirst() 29 | } 30 | } 31 | 32 | var stringQueue = Queue() 33 | stringQueue.enqueue("First") 34 | stringQueue.enqueue("Second") 35 | stringQueue.enqueue("Third") 36 | stringQueue.dequeue() 37 | stringQueue.enqueue("Fourth") 38 | print(stringQueue) 39 | 40 | if let peekElement = stringQueue.peek { 41 | print("Peek element: \(peekElement)") 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /learn_data_structure.playground/Pages/Queue (With Linked List).xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | 2 | class Node: CustomStringConvertible { 3 | 4 | var value: T 5 | var next: Node? 6 | 7 | var description: String { 8 | guard let next = next else { return "\(value)" } 9 | return "\(value) -> " + String(describing: next) 10 | } 11 | 12 | init(value: T, next: Node? = nil) { 13 | self.value = value 14 | self.next = next 15 | } 16 | } 17 | 18 | 19 | struct Queue: CustomStringConvertible { 20 | 21 | var front: Node? 22 | 23 | var rear: Node? 24 | 25 | init() { } 26 | 27 | var isEmpty: Bool { 28 | return front == nil 29 | } 30 | 31 | var description: String { 32 | guard let front = front else { return "Empty Queue" } 33 | return String(describing: front) 34 | } 35 | 36 | var peek: T? { 37 | return front?.value 38 | } 39 | } 40 | 41 | extension Queue { 42 | 43 | mutating private func push(_ value: T) { 44 | front = Node(value: value, next: front) 45 | if rear == nil { 46 | rear = front 47 | } 48 | } 49 | 50 | mutating func enqueue(_ value: T) { 51 | if isEmpty { 52 | self.push(value) 53 | return 54 | } 55 | 56 | rear?.next = Node(value: value) 57 | rear = rear?.next 58 | } 59 | 60 | mutating func dequeue() -> T? { 61 | defer { 62 | front = front?.next 63 | if isEmpty { 64 | rear = nil 65 | } 66 | } 67 | return front?.value 68 | } 69 | } 70 | 71 | var stringQueue = Queue() 72 | stringQueue.enqueue("First") 73 | stringQueue.enqueue("Second") 74 | stringQueue.enqueue("Third") 75 | stringQueue.dequeue() 76 | stringQueue.enqueue("Fourth") 77 | print(stringQueue) 78 | if let peekElement = stringQueue.peek { 79 | print("Peek element: \(peekElement)") 80 | } 81 | 82 | -------------------------------------------------------------------------------- /learn_data_structure.playground/Pages/Singly LInked List.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | 2 | // ***************** Singly Linked List ********************* 3 | 4 | // A class to hold the information for an element 5 | class Node: CustomStringConvertible, Equatable { 6 | 7 | var value: T 8 | var next: Node? 9 | 10 | // required conforms to CustomStringConvertible 11 | var description: String { 12 | guard let next = next else { return "\(value)" } 13 | return "\(value) -> " + String(describing: next) 14 | } 15 | 16 | init(value: T, next: Node? = nil) { 17 | self.value = value 18 | self.next = next 19 | } 20 | 21 | // required conforms to Equatable 22 | static func ==(lhs: Node, rhs: Node) -> Bool { 23 | return lhs.next == rhs.next 24 | } 25 | } 26 | 27 | 28 | // A struct to hold the information of all the nodes 29 | struct LinkedList: CustomStringConvertible { 30 | 31 | // to hold the starting point of list 32 | var head: Node? 33 | 34 | // to hold the ending point of list 35 | var tail: Node? 36 | 37 | init() { } 38 | 39 | // if head is nil simply list is empty right now 40 | var isEmpty: Bool { 41 | return head == nil 42 | } 43 | 44 | // required conforms to CustomStringConvertible 45 | var description: String { 46 | guard let head = head else { return "Empty list" } 47 | return String(describing: head) 48 | } 49 | } 50 | 51 | // Common Methods 52 | extension LinkedList { 53 | 54 | // get a node from a specific position 55 | func node(at index: Int) -> Node? { 56 | 57 | // if list is empty then simply return nil 58 | if isEmpty { 59 | return nil 60 | } 61 | 62 | var currentNode = head 63 | var currentIndex = 0 64 | while currentNode != nil && currentIndex < index { 65 | currentNode = currentNode?.next 66 | currentIndex += 1 67 | } 68 | return currentNode 69 | } 70 | 71 | // get number of nodes in the list 72 | func numberOfNodes() -> Int { 73 | var currentNode = head 74 | var count = 0 75 | while currentNode != nil { 76 | currentNode = currentNode?.next 77 | count += 1 78 | } 79 | return count 80 | } 81 | 82 | // to remove all the nodes from the list 83 | mutating func removeAll() { 84 | head = nil 85 | tail = nil 86 | } 87 | } 88 | 89 | 90 | // Insertion Methods 91 | extension LinkedList { 92 | 93 | // push: adding a value at the front of the list, called as Head-first insertion 94 | mutating func push(_ value: T) { 95 | 96 | // create a new node and passing head (starting point) as a next node 97 | let newNode = Node(value: value, next: head) 98 | 99 | // change the head to the new node because head will hold the starting node 100 | head = newNode 101 | 102 | // if tail (ending node) is nil, it means head and tail pointing the same node as it is first node 103 | if tail == nil { 104 | tail = head 105 | } 106 | } 107 | 108 | 109 | // append: adding a value at the end of the list, called as Tail-end intersion 110 | mutating func append(_ value: T) { 111 | 112 | // if list is empty then simply perform push operation 113 | if isEmpty { 114 | self.push(value) 115 | return 116 | } 117 | 118 | // create new node and assign it to tail's next because tail will always point the last node 119 | tail?.next = Node(value: value) 120 | 121 | // replace the tail with tail's next because before doing it tail's next pointing the last node 122 | tail = tail?.next 123 | } 124 | 125 | // insert: adding a value after a specific node. 126 | mutating func insert(_ value: T, after index: Int) { 127 | 128 | // if given index is not valid as per current list, it will be added in last 129 | if index < 0 || index >= self.numberOfNodes() { 130 | self.append(value) 131 | return 132 | } 133 | 134 | // if node not found just before to given insert index, perform push operation 135 | if let beforeNode = self.node(at: index), let tail = tail { 136 | 137 | // if insert index ie equal to last, simply append new node at last 138 | if beforeNode == tail { 139 | self.append(value) 140 | } else { 141 | // create new node and assign as a next node for the before node 142 | beforeNode.next = Node(value: value, next: beforeNode.next) 143 | } 144 | } else { 145 | self.push(value) 146 | } 147 | } 148 | } 149 | 150 | // Deletion Methods 151 | extension LinkedList { 152 | 153 | 154 | // pop: remove an element from the front of the list 155 | // discardableResult: Using this to avoid the return value after pop if we don't care about return value. It will not give any warning if we don't assign the result to any variable or constant. 156 | @discardableResult 157 | mutating func pop() -> T? { 158 | 159 | // A defer statement is used for executing code just before transferring program control outside of the scope that the statement appears in. 160 | // here, we are using defer to perform pop operation performed later to return the popped value. 161 | // popped value will return first then defer block will be execute. 162 | defer { 163 | head = head?.next 164 | if isEmpty { 165 | tail = nil 166 | } 167 | } 168 | return head?.value 169 | } 170 | 171 | 172 | 173 | // deleteLast: remove the last element of the list 174 | @discardableResult 175 | mutating func deleteLast() -> T? { 176 | 177 | // if head is nil, means no node exists. 178 | guard let head = head else { return nil } 179 | 180 | // if head is not have any reference of next node, it means we have only one node in list. 181 | guard head.next != nil else { return pop() } 182 | 183 | // first we have to traverse to reach at last two nodes. 184 | var currentNode = head 185 | var previousNode = head 186 | 187 | while let next = currentNode.next { 188 | previousNode = currentNode 189 | currentNode = next 190 | } 191 | 192 | // disconnected the next of last previous node 193 | previousNode.next = nil 194 | tail = previousNode 195 | return currentNode.value 196 | } 197 | 198 | 199 | // removeAt: remove an element from a specific position 200 | mutating func remove(after index: Int) -> T? { 201 | 202 | if index < 0 || index >= self.numberOfNodes() { 203 | return nil 204 | } 205 | 206 | if let beforeNode = self.node(at: index) { 207 | defer { 208 | if beforeNode.next == tail { 209 | tail = beforeNode 210 | } 211 | beforeNode.next = beforeNode.next?.next 212 | } 213 | return beforeNode.next?.value 214 | } 215 | return nil 216 | } 217 | 218 | } 219 | 220 | 221 | 222 | var numberLinkedList = LinkedList() 223 | numberLinkedList.push(10) 224 | numberLinkedList.append(15) 225 | numberLinkedList.push(20) 226 | numberLinkedList.append(25) 227 | numberLinkedList.push(30) 228 | numberLinkedList.append(35) 229 | numberLinkedList.push(40) 230 | numberLinkedList.append(45) 231 | numberLinkedList.push(50) 232 | numberLinkedList.insert(12, after: 0) 233 | 234 | print("Total number of nodes in Number Linked List: ", numberLinkedList.numberOfNodes(), "and Elements are: ", numberLinkedList) 235 | 236 | print(" ----- Value popped ----- ", numberLinkedList.pop() ?? 0) 237 | if let poppedValue = numberLinkedList.pop() { 238 | print("Total number of nodes after popped the value: \(poppedValue) in Number Linked List: ", numberLinkedList.numberOfNodes(), "and Elements are: ", numberLinkedList) 239 | } 240 | 241 | if let deletedValue = numberLinkedList.deleteLast() { 242 | print("Total number of nodes after deleted the last value: \(deletedValue) in Number Linked List: ", numberLinkedList.numberOfNodes(), "and Elements are: ", numberLinkedList) 243 | } 244 | 245 | if let removedValue = numberLinkedList.remove(after: 4) { 246 | print("Total number of nodes after removed the value: \(removedValue) in Number Linked List: ", numberLinkedList.numberOfNodes(), "and Elements are: ", numberLinkedList) 247 | } 248 | 249 | 250 | var stringLinkedList = LinkedList() 251 | stringLinkedList.push("Alex") 252 | stringLinkedList.append("Mariya") 253 | stringLinkedList.push("Tina") 254 | stringLinkedList.append("Micheal") 255 | stringLinkedList.insert("Richard", after: 0) 256 | stringLinkedList.insert("Onam", after: 12) 257 | 258 | print("Total number of nodes in String Linked List: ", stringLinkedList.numberOfNodes(), "and Elements are: ", stringLinkedList) 259 | 260 | print(" ----- Value popped ----- ", stringLinkedList.pop() ?? 0) 261 | if let poppedValue = stringLinkedList.pop() { 262 | print("Total number of nodes after popped the value: \(poppedValue) in String Linked List: ", stringLinkedList.numberOfNodes(), "and Elements are: ", stringLinkedList) 263 | } 264 | 265 | if let deletedValue = stringLinkedList.deleteLast() { 266 | print("Total number of nodes after deleted the last value: \(deletedValue) in String Linked List: ", stringLinkedList.numberOfNodes(), "and Elements are: ", stringLinkedList) 267 | } 268 | 269 | if let removedValue = stringLinkedList.remove(after: 1) { 270 | print("Total number of nodes after removed the value: \(removedValue) in String Linked List: ", stringLinkedList.numberOfNodes(), "and Elements are: ", stringLinkedList) 271 | } 272 | 273 | /* 274 | ------- Time Complexity for all the insertion operations ------- 275 | Push: Adding a new node at the first in the list. So the time complexity will be O(1) 276 | 277 | Append: Adding a new node at the last in the list. So the time complexity will be O(1) 278 | 279 | Insert: Adding a new node at the specific position in the list. So the traversing will be performed to find out the node just before the given index, so the time complexity will be O(n); n = insertion index 280 | 281 | 282 | ------- Time complexity for all the deletion operations ------- 283 | Pop: Removing the node from the first in the list. So the time complexity will be O(1) 284 | 285 | deleteLast: Removing the node from the last in the list. But to remove the last, we have to traverse in the list till tail, so the time complexity will be O(n) 286 | 287 | removeAt: Removing the node from a specific position in the list. So the traversing will be performed to find out the node just before the given index, so the time complexity will be O(n); n = deletion index 288 | */ 289 | 290 | -------------------------------------------------------------------------------- /learn_data_structure.playground/Pages/Stack (Array).xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | 2 | 3 | struct Stack: CustomStringConvertible, TestProtocol { 4 | 5 | // array of items 6 | var items: [T] = [] 7 | 8 | // to print the formatted description 9 | var description: String { 10 | return "---- Stack begin ----\n" + 11 | items.map({ "\($0)" }).joined(separator: "\n") + 12 | "\n---- Stack End ----" 13 | } 14 | 15 | mutating func push(_ item: T) { 16 | self.items.insert(item, at: 0) 17 | } 18 | 19 | @discardableResult 20 | mutating func pop() -> T? { 21 | if items.isEmpty { return nil } 22 | return self.items.removeFirst() 23 | } 24 | 25 | func peek() -> T? { 26 | return self.items.first 27 | } 28 | } 29 | 30 | 31 | var stackString = Stack() 32 | stackString.push("First") 33 | stackString.push("Second") 34 | stackString.push("Third") 35 | stackString.pop() 36 | if let peekItem = stackString.peek() { 37 | print("Peek Item in Stack: ", peekItem) 38 | } 39 | print(stackString) 40 | 41 | 42 | 43 | var stackInt = Stack() 44 | stackInt.push(10) 45 | stackInt.push(20) 46 | stackInt.push(30) 47 | stackInt.pop() 48 | if let peekItem = stackInt.peek() { 49 | print("Peek Item in Stack: ", peekItem) 50 | } 51 | print(stackInt) 52 | 53 | 54 | -------------------------------------------------------------------------------- /learn_data_structure.playground/Pages/Stack (Without Array).xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Node class to hold the data 4 | class Node: CustomStringConvertible { 5 | 6 | let value: T 7 | var next: Node? 8 | 9 | var description: String { 10 | guard let next = next else { return "\(value)" } 11 | return "\(value)\n" + String(describing: next) 12 | } 13 | 14 | init(value: T) { 15 | self.value = value 16 | } 17 | } 18 | 19 | 20 | // Stack class to hold the all items 21 | class Stack: CustomStringConvertible { 22 | 23 | var top: Node? 24 | 25 | var description: String { 26 | guard let top = top else { return "---- Stack is EMPTY ----" } 27 | return "---- Stack Begin ----\n" + String(describing: top) + "\n---- Stack End ----" 28 | } 29 | 30 | func push(_ value: T) { 31 | let currentTop = top 32 | top = Node(value: value) 33 | top?.next = currentTop 34 | } 35 | 36 | @discardableResult 37 | func pop() -> T? { 38 | let currentTop = top 39 | top = top?.next 40 | return currentTop?.value 41 | } 42 | 43 | func peek() -> T? { 44 | return top?.value 45 | } 46 | } 47 | 48 | 49 | 50 | var stackString = Stack() 51 | stackString.push("First") 52 | if let poppedItem = stackString.pop() { 53 | print("[\(poppedItem)] is popped from stack.") 54 | } 55 | stackString.push("Second") 56 | stackString.push("Third") 57 | print(stackString) 58 | 59 | 60 | 61 | 62 | 63 | struct Student { 64 | let name: String 65 | let age: Int 66 | } 67 | 68 | let alex = Student(name: "Alex Murphy", age: 25) 69 | let smith = Student(name: "Smith John", age: 34) 70 | let rita = Student(name: "Rita Martin", age: 22) 71 | 72 | var stackStudent = Stack() 73 | stackStudent.push(alex) 74 | stackStudent.push(smith) 75 | stackStudent.push(rita) 76 | stackStudent.pop() 77 | print(stackStudent) 78 | 79 | -------------------------------------------------------------------------------- /learn_data_structure.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | --------------------------------------------------------------------------------