Skip to content
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 ImplementHashMapUsingLinearChaining.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// ImplementHashMapUsingLinearChaining.swift
// DSA-Practice
//
// Created by Paridhi Malviya on 12/29/25.
//

class MyHashMap {
class LCNode {
var key: Int
var value: Int
var next: LCNode?

init(key: Int, value: Int, next: LCNode? = nil) {
self.key = key
self.value = value
self.next = next
}
}

var storage: [LCNode?]

private var buckets: Int
private func hash(key: Int) -> Int {
return key % buckets
}

//storage will be an arry of linked lists.
init() {
//an array of 10000 elements while having range from 0 to 1 million (for input)
self.storage = Array(repeating: nil, count: 10000)
buckets = 10000
}

//for below three functions, this function will be used
private func find(head: LCNode, key: Int) -> LCNode {
//set previous pointer to head of the linked list
var prev = head //at head we will be having a dummy node.
var current = head.next
//Stop when the current reaches the length or we find the value
while (current != nil && current?.key != key) {
prev = current!
current = current?.next
}
return prev
}

func put(key: Int, value: Int) {
let index = hash(key: key)
if (storage[index] != nil) {
//traverse through this linked list
//thers is no linked list, so initiate the linked list
storage[index] = LCNode(key: -1, value: -1)
}
//when linked list is already there
let prev = find(head: storage[index]!, key: key)
//if key is in the current linked list.

//if current key is not there in the list
//it will tell us that the current node is not present in the node.
if (prev.next == nil) {
let newNode = LCNode(key: key, value: value)
prev.next = newNode
} else {
//current key is there.
prev.next?.value = value
}
}

func get(key: Int) -> Int {
let index = hash(key: key)
if (storage[index] == nil) {
return -1
}
let prev = find(head: storage[index]!, key: key)
if (prev.next == nil) {
return -1
}

return prev.next!.value
}

//key is equal to the index of the array we took
func remove(key: Int) {
let index = hash(key: key)
//If linked list is not present then return
if (storage[index] == nil) {
return
}

//otherwise traverse through the linked list
let prev: LCNode = find(head: storage[index]!, key: key)
if (prev.next == nil) {
return
}
let temp: LCNode = prev.next!
prev.next = prev.next?.next
temp.next = nil
}
}
53 changes: 53 additions & 0 deletions Implment queue using stacks/ImplementQueueUsingTwoStacks.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// ImplementQueueUsingTwoStacks.swift
// DSA-Practice
//
// Created by Paridhi Malviya on 12/30/25.
//

//Implment queue using 2 stacks.

class QueueImpl {
var inStack = StackUsingLL(llList: LLLinkedList<Int>())
var outStack = StackUsingLL(llList: LLLinkedList<Int>())

func push(element: Int) {
//push element in stack1
inStack.push(value: element)
}

func pop() -> Int? {
if (outStack.isEmpty()) {
while (!inStack.isEmpty()) {
//push all elements from stack1 to stack2 and then pop
outStack.push(value: inStack.pop()!)
}
}
return outStack.pop()
}

func peek() -> Int? {
while (!inStack.isEmpty()) {
outStack.push(value: inStack.pop()!)
}
return outStack.peek()
}

func isEmpty() -> Bool {
return (inStack.isEmpty() && outStack.isEmpty())
}

init() {
let inputArray: [Any] = [4, 2, 1, 3, 5, "P", 6, 7, "P", "P"]
for element in inputArray {
if (element as? String != "P") {
push(element: element as! Int)
} else {
let poppedElement = pop()
print("poppedElement \(poppedElement, default: "NA")")
}
}
print("stack1 \(inStack.description)")
print("stack2 \(outStack.description)")
}
}
159 changes: 159 additions & 0 deletions Implment queue using stacks/LinkedListToStackAdapter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
//
// LinkedListToStackAdapter.swift
// DSA-Practice
//
// Created by Paridhi Malviya on 12/16/25.
//

//Implement stack using linked list

class LLNode<T> {
var value: T
var next: LLNode<T>?

init(value: T, next: LLNode<T>?) {
self.value = value
self.next = next
}
}

class LLLinkedList<T> {
private var head: LLNode<T>?
private var tail: LLNode<T>?

var isEmpty: Bool {
return head == nil
}

var count: Int {
var currentHead = head
var count = 0
while (currentHead != nil) {
count += 1
currentHead = currentHead?.next
}
return count
}

init() {

}
}

extension LLLinkedList {
func append(value: T) {
let newNode = LLNode(value: value, next: nil)
if head == nil {
//means linkedlist is empty, so set the newnode as the head and tail both
tail = newNode
head = newNode
} else {
//if linked list is not empty then do normal appending
tail?.next = newNode
tail = newNode
}
}

func prepend(value: T) {
let newNode = LLNode(value: value, next: nil)
if head == nil {
//linked list is empty
head = LLNode(value: value, next: nil)
tail = head
} else {
// linked list is not empty
newNode.next = head
head = newNode
}
}

func removeFirstNode() -> LLNode<T>? {
if (head == nil) {
//it means the ll is empty
return nil
} else {
//if the ll is not empty
let currentHead = head
if let nextNode = head?.next {
head = nextNode
} else if (head?.next == nil) {
head = nil
}
return currentHead
}
}

var currentHead: LLNode<T>? {
return head
}
}

extension LLLinkedList: CustomStringConvertible {
var description: String {
var currentNode = head
var descString = "["
while currentNode != nil {
descString += "\(String(describing: currentNode?.value))"
currentNode = currentNode?.next
if (currentNode != nil) {
descString += ","
}
}
return descString + "]"
}
}

class StackUsingLL<T>: CustomStringConvertible {
private var llList: LLLinkedList<T>?

init(llList: LLLinkedList<T>) {
self.llList = llList
}

func push(value: T) {
//append the first element at the start of the linked list
llList?.prepend(value: value)
}

func pop() -> T? {
//remove the first node from the linked list and return it.
let removedItem = llList?.removeFirstNode()
return removedItem?.value
}

func peek() -> T? {
return llList?.currentHead?.value
}

func isEmpty() -> Bool {
return llList?.isEmpty ?? true
}

var description: String {
var currentHead = llList?.currentHead
var descString = "["
while (currentHead != nil) {
descString += "\(currentHead!.value)"
currentHead = currentHead!.next
if (currentHead != nil) {
descString += ","
}
}
return descString + "]"
}
}

class LinkedListToStackAdapter {

init() {
let stack = StackUsingLL<Int>(llList: LLLinkedList())
stack.push(value: 2)
stack.push(value: 3)
stack.push(value: 6)
let poppedElement = stack.pop()
print("popped element \(poppedElement, default: "NA")")
let topElement = stack.peek()
print("topElement \(topElement, default: "NA")")
print("printed linked list \(stack.description)")
}
}