Skip to content

Commit

Permalink
Merge branch 'TheAlgorithms:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Kedar-27 authored Apr 19, 2024
2 parents 05e6123 + 00ac786 commit b5562ba
Show file tree
Hide file tree
Showing 4 changed files with 339 additions and 0 deletions.
6 changes: 6 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

Expand Down
194 changes: 194 additions & 0 deletions data_structures/doubly_linked_list/DoublyLinkedList.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import Foundation

public class Node<Value> {
public var value: Value?
public var next: Node?
public var prev: Node?

public init(value: Value? = nil, next: Node<Value>? = nil, prev: Node<Value>? = nil) {
self.value = value
self.next = next
self.prev = prev
}
}

extension Node: CustomStringConvertible {
public var description: String {
guard let next: Node<Value> = self.next else {
return "\(String(describing: value))"
}
return "\(String(describing: value)) <-> \(String(describing: next)) "
}
}

public struct DoublyLinkedList<Value> {

public var head: Node<Value>?
public var tail: Node<Value>?
public var count: Int = 0

public var isEmpty: Bool {
return head == nil
}

public mutating func push(_ value: Value) {
let new: Node<Value> = 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<Value>) -> Node<Value> {
guard tail !== node else {
append(value)
return tail!
}
var new: Node<Value> = 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<Value>) -> Node<Value> {
guard head !== node else {
push(value)
return head!
}
var new: Node<Value> = 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<Value>? {
guard index > -1 || index < count else { return nil }

let startFromTail: Bool = index > count / 2
var currentNode: Node<Value>? = 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>) -> Value? {
defer {
if node.next != nil {
count -= 1
}
if node.next === tail {
tail = node
}
if let next2node: Node<Value> = node.next?.next {
next2node.prev = node
}
node.next = node.next?.next
}
return node.next?.value
}

@discardableResult
public mutating func remove(before node: Node<Value>) -> Value? {
defer {
if node.prev != nil {
count -= 1
}
if node.prev === head {
head = node
}
if let prev2node: Node<Value> = 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<Value> = self.head else {
return "Empty list"
}
return String(describing: head)
}
}

// Here are testing scenarios to run in a Swift playground

/*
var list = DoublyLinkedList<Int>()

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)
*/
75 changes: 75 additions & 0 deletions graph/BFS/BFS.swift
Original file line number Diff line number Diff line change
@@ -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..<sizeOfQueue {
let currNode = nodesOfCurrentLevel[index]
if(visited[currNode] == true){
continue
}
print("\(currNode) ")
visited[currNode] = true
guard let neighbors = graph[currNode]?.neighbors else { continue }
for neigh in neighbors {
if visited[neigh] == false {
nodesOfNextLevel.append(neigh)
}
}
}
nodesOfCurrentLevel = nodesOfNextLevel
}
}
}
}

// MARK: - Input Graph
func setup() {
let edges = [
Edge(from: 1, to: 2),
Edge(from: 1, to: 4),
Edge(from: 2, to: 3),
Edge(from: 2, to: 4),
Edge(from: 2, to: 5),
Edge(from: 3, to: 5),
Edge(from: 4, to: 5),
Edge(from: 4, to: 6),
Edge(from: 5, to: 6),
Edge(from: 5, to: 6),
Edge(from: 6, to: 7),
]
testBFS(edges: edges)
}

setup()
64 changes: 64 additions & 0 deletions graph/DFS/DFS.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// 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: - DFS Recursion
func dfs(vertex: Int, visited: inout [Bool], graph: [Int: Node]) {
if visited[vertex] == true {
return
}
visited[vertex] = true
print("\(vertex) ")
guard let neighbors = graph[vertex] else { return }
for neighbor in neighbors.neighbors {
dfs(vertex: neighbor, visited: &visited, graph: graph)
}
}

func testDFS(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)
for node in 1...graph.count {
if visited[node] == false {
dfs(vertex: node, visited: &visited, graph: graph)
}
}
}


// MARK: - setup
func setup() {
let edges = [
Edge(from: 1, to: 2),
Edge(from: 1, to: 4),
Edge(from: 2, to: 3),
Edge(from: 2, to: 4),
Edge(from: 2, to: 5),
Edge(from: 3, to: 5),
Edge(from: 4, to: 5),
Edge(from: 4, to: 6),
Edge(from: 5, to: 6),
Edge(from: 5, to: 6),
Edge(from: 6, to: 7),
]
testDFS(edges: edges)
}

0 comments on commit b5562ba

Please sign in to comment.