How to implement doubly linked list in swift? - swift

How can I implement a doubly linked list in Swift with all the operations like insert and deletion?
I know how to implement singly linked list but I can't find a way to make it a doubly linked list. I am a beginner in coding.
import UIKit
struct LinkedList<Value> {
var Head : node<Value>?
var Tail : node<Value>?
var isEmpty : Bool {
return Head == nil
}
// to add at the beginning of the list
mutating func push(_ value : Value) {
Head = node(value: value, nextNode: Head)
if Tail == nil {
Tail = Head
}
}
// to add at the end of the list
mutating func append(_ value : Value) {
guard !isEmpty else {
push(value)
return
}
let newNode = node(value: value)
Tail?.nextNode = newNode
Tail = newNode
}
//to find the node at particular index
func findNode(at index: Int) -> node<Value>? {
var currentIndex = 0
var currentNode = Head
while(currentNode != nil && currentIndex < index) {
currentNode = currentNode?.nextNode
currentIndex += 1
}
return currentNode
}
// to insert at a particular location
func insert(_ value : Value, afterNode : node<Value>) {
afterNode.nextNode = node(value: value, nextNode: afterNode.nextNode)
}
mutating func pop() -> Value? {
defer {
Head = Head?.nextNode
if isEmpty {
Head = nil
}
}
return Head?.value
}
mutating func removeLast() -> Value? {
guard let head = Head else {
return nil
}
guard head.nextNode != nil else {
return pop()
}
var previous = head
var current = head
while let next = current.nextNode {
previous = current
current = next
}
previous.nextNode = nil
Tail = previous
return current.value
}
mutating func remove(after node : node<Value>?) -> Value? {
defer {
if node === Tail {
Tail = node
}
node?.nextNode = node?.nextNode?.nextNode
}
return node?.nextNode?.value
}
}
extension LinkedList : CustomStringConvertible {
var description: String {
guard let linkedListHead = Head else {
return "Empty List"
}
return String(describing: linkedListHead)
}
}
class node<Value> {
var value : Value
var nextNode : node?
init(value : Value , nextNode : node? = nil) {
self.value = value
self.nextNode = nextNode
}
}
extension node : CustomStringConvertible {
var description: String {
guard let nextValue = nextNode else { return "\(value)" }
return "\(value) -> " + String(describing: nextValue) + " "
}
}
var listOfIntegers = LinkedList<Int>()
var listOfStrings = LinkedList<String>()
listOfIntegers.push(1)
listOfIntegers.push(3)
listOfIntegers.push(4)
listOfIntegers.append(6)
let nodeInfo = listOfIntegers.findNode(at: 1)!
listOfIntegers.insert(8, afterNode: nodeInfo)
print(listOfIntegers)
listOfStrings.push("hello")
listOfStrings.push("Sardar Ji!")
print(listOfStrings)
let index = 3
let node2 = listOfIntegers.findNode(at: index - 1)
listOfIntegers.remove(after: node2)
print(listOfIntegers)
I want to implement doubly linked list the same way and the output should be like this:
node1 <-> node2 <-> node3

//here is the full implementaion of doubly-linked-list in swift. updates will be appreciated.
import Foundation
struct DoublyLinkedList<DataItem> {
fileprivate var head : Node<DataItem>?
fileprivate var tail : Node<DataItem>?
var isEmpty : Bool {
return head == nil
}
//to add at the beginning
mutating func InsertAtBeginning(_ dataItem : DataItem) {
let node = Node(dataItem: dataItem, nextNode: head, previousNode: nil)
head?.previousNode = node
head = node
if tail == nil {
tail = head
}
}
//to add at the end
mutating func insertAtEnd(_ dataItem : DataItem) {
guard !isEmpty else {
InsertAtBeginning(dataItem)
return
}
let newNode = Node(dataItem: dataItem, nextNode: nil, previousNode: tail)
tail?.nextNode = newNode
//newNode.previousNode = tail
tail = newNode
}
//to insert at particular node
func insertParticularly(_ dataItem : DataItem , afterNode : Node<DataItem>) {
let node = Node(dataItem: dataItem)
afterNode.nextNode?.previousNode = node
node.nextNode = afterNode.nextNode
afterNode.nextNode = node
node.previousNode = afterNode
}
//to find a node at particular index
func findNode(at index : Int) -> Node<DataItem>? {
var currentIndex = 0
var currentNode = head
while currentNode != nil && currentIndex < index {
currentNode = currentNode?.nextNode
currentIndex += 1
}
return currentNode
}
//MARK:- remove functionality
//remove the first element
mutating func removeFirst() -> DataItem? {
defer {
head = head?.nextNode
if isEmpty {
head = nil
}
}
return head?.dataItem
}
// remove the last element
mutating func removeLast() -> DataItem? {
guard let headValue = head else {
return nil
}
guard headValue.nextNode != nil else {
return removeFirst()
}
var previous = headValue
var current = headValue
while let next = current.nextNode {
previous = current
current = next
}
previous.nextNode = nil
tail = previous
return current.dataItem
}
// remove from a specific location
mutating func removeAt(at node : Node<DataItem>?) -> DataItem? {
defer {
if node === tail {
removeLast()
}
node?.previousNode?.nextNode = node?.nextNode
node?.nextNode?.previousNode = node?.previousNode
}
return node?.nextNode?.dataItem
}
}
extension DoublyLinkedList : CustomStringConvertible {
var description : String {
guard let doublyLinkedListHead = head else { return "UnderFlow"}
//return String(describing: doublyLinkedListHead)
return doublyLinkedListHead.linkedDescription
}
}
class Node<DataItem> {
var dataItem : DataItem
var nextNode : Node?
var previousNode : Node?
init(dataItem : DataItem , nextNode : Node? = nil , previousNode : Node? = nil) {
self.dataItem = dataItem
self.nextNode = nextNode
self.previousNode = previousNode
}
}
extension Node : CustomStringConvertible {
var description: String {
return ((previousNode == nil) ? "nil" : "\(previousNode!.dataItem)") +
" <-> \(dataItem) <-> " +
((nextNode == nil) ? "nil" : "\(nextNode!.dataItem)")
}
var linkedDescription: String {
return "\(dataItem)" + ((nextNode == nil) ? "" : " <-> \(nextNode!.linkedDescription)")
}
}
var list = DoublyLinkedList<Int>()
list.InsertAtBeginning(4)
list.insertAtEnd(5)
list.insertAtEnd(4)
list.insertAtEnd(7)
list.insertAtEnd(2)
list.insertAtEnd(0)
list.description
let node1 = list.findNode(at: 3)
node1?.previousNode
list.head

Fundamentally, your problem is that you've got head and tail pointers in LinkedList, but node only has nextNode pointer. If node is the structure representing each item in the list, and if you want to be able to traverse the list in either direction, then each item needs a link to the next item and also the previous item. That's why they call it a "doubly linked list" after all.
Add a previousNode pointer to your node structure.
Go find every spot in your code where you modify a nextNode pointer and change the code to also maintain the previousNode pointer.

Related

Reversing list of nodes

I have the following Node class which points to a next node :
class Node<T> {
var data: T
var next: Node<T>?
init(data: T, next: Node<T>?) {
self.data = data
self.next = next
}
}
and I wrote a method to reverse the data , for example
let list = Node<Int>(data:1,next :Node<Int>(data:2,next :Node<Int>(data :3,next :nil)))
which has values 1,2,3 should have values 3,2,1
here is my function :
extension Node {
func reverse() {
var firstNode = self
var previousNode: Node<T>? = nil
var currentNode = firstNode
var nextNode = firstNode.next
while nextNode != nil {
currentNode.next = previousNode
previousNode = currentNode
currentNode = nextNode!
nextNode = currentNode.next
}
currentNode.next = previousNode
firstNode = currentNode
var current = firstNode as Node<T>?
//print 3 2 1
while(current != nil)
{
print(current!.data)
current = current!.next
}
}
}
The printing in the method indeed displays "3 2 1" however, how can I set it to the current object to be the reversed list? Assigning at the end "self = current" seems to be prohibited.
Your list is just a variable of Node<Int> - i.e. a pointer to the head node.
You cannot mutate self to be a reference to a different node - the tail node in the original list, but you could return the last node and re-assign what list points to:
var list = Node<Int>(...)
list = list.reverse()
The reverse function would need to return a Node<T> type:
func reverse() -> Node<T> {
// your algorithm
// ...
return firstNode
}
Btw, your code doesn't account for cycles in the list. If some node points to one of its previous nodes, then your while nextNode != nil will become an infinite loop.
You have no way to know what your linked list is. Add one:
class Node<T> : CustomStringConvertible {
var data: T
var next: Node<T>?
init(data: T, next: Node<T>?) {
self.data = data
self.next = next
}
var description: String {
var s = ""
var node = Optional(self)
while node != nil {
s.append(String(describing:node!.data))
node = node?.next
}
return(s)
}
}
Now it's easy to see that your reverse is working. All you have to do is have it produce a value.
extension Node {
func reverse() -> Node? {
var firstNode = self
var previousNode: Node<T>? = nil
var currentNode = firstNode
var nextNode = firstNode.next
while nextNode != nil {
currentNode.next = previousNode
previousNode = currentNode
currentNode = nextNode!
nextNode = currentNode.next
}
currentNode.next = previousNode
firstNode = currentNode
let current = firstNode as Node<T>?
return current
}
}
Here's a test:
let list = Node<Int>(data:1,next :Node<Int>(data:2,next :Node<Int>(data :3,next :nil)))
print(list) // 123
if let newlist = list.reverse() {
print(newlist) // 321, yay!
}

Insert node in singly linked list in swift playground

Given a singly linked list, the task is to write a program to insert that element in a linked list in Swift.
import UIKit
class Node<T: Equatable>{
var value:T?
var nextNode:Node?
}
class LinkedList<T: Equatable>{
var headNode = Node<T>()
func insert(value: T){
if headNode.value == nil{
headNode.value = value
}else{
var lastNode = headNode
while lastNode.nextNode != nil {
lastNode = lastNode.nextNode!
}
let newNode: Node = Node<T>()
newNode.value = value
lastNode.nextNode = newNode
}
}
func printAllKeys() {
var currentNode: Node! = headNode
print("---------------")
while currentNode != nil && currentNode.value != nil {
print("The item is \(currentNode.value!)")
currentNode = currentNode.nextNode
}
}
}
var list = LinkedList<Int>()
list.insert(value: 5)
list.insert(value: 10)
list.printAllKeys()

DFS in Swift not terminating

My implementation of a BFS works fine:
func bfsReturnVals() -> [Int] {
// bfs uses a queue.
var queue = [Node]()
var queueVals = [Int]()
queue.append(self)
while let head = queue.first {
if let lft = head.left {
queue.append(lft)
}
if let rgt = head.right {
queue.append(rgt)
}
queueVals.append(queue[0].data)
queue.removeFirst()
}
return queueVals
}
But I usually code a DFS recursively. Now my similar implementation of DFS does not terminate
func dfsReturnVals() -> [Int] {
var stack = [Node]()
var queueVals = [Int]()
stack.append(self)
while let tail = stack.last {
if let lft = tail.left {
stack.append(lft)
}
if let rgt = tail.right {
stack.append(rgt)
}
queueVals.append(stack[stack.count - 1].data)
stack.removeLast()
}
return queueVals
}
I can't work out why. Shouldn't removeLast() work just like removeFirst()?
My node class is as follows:
class Node : CustomStringConvertible {
var description : String {return "\(self.data)" }
var data : Int
var left: Node?
var right: Node?
init(_ data: Int) {
self.data = data
}
func insert(_ data: Int) {
if data < self.data {
if let lft = self.left {
lft.insert(data)
} else {
let newNode = Node(data)
left = newNode
}
} else {
if let rgt = self.right {
rgt.insert(data)
} else {
let newNode = Node(data)
right = newNode
}
}
}
}
When you remove the last item from the stack, you're removing the items you just pushed on. In your bfs implementation, remove first will grab the intended parent node regardless of the fact that you do it at the end of the loop, because you add the children to the end of the queue. You should move the operation to remove the expanded node from your stack to before you push new nodes on.

Successor of a node in a Binary Search Tree - Swift

Trying to solve the successor for a nod in a binary tree s.t. the tree
has the following successors: for 8 -> 10, 10 -> 12 and 14 -> 20
However, for 10 I'm returning nil (and, indeed for 14 I'm returning nil).
My algorithm is:
func inorderSucc(_ node: Node? = nil) -> Node? {
if (node == nil) {
return nil
} else {
if let rhn = node?.right {
return leftMostChild(rhn)
} else {
var q = node
var x = node?.parent
while (x != nil && x!.left != q) {
q = x
x = x?.parent
}
return x
}
}
}
func leftMostChild(_ n: Node) -> Node? {
var node = n
while (node.left != nil) {
node = node.left!
}
return node
}
Calling a tree:
class Node : CustomStringConvertible, Hashable{
var hashValue : Int { return data}
static func == (lhs: Node, rhs: Node) -> Bool {
return lhs.data == rhs.data
}
var data : Int
var left : Node?
var right : Node?
var parent : Node? = nil
var description: String {
return String(data) + (left?.description ?? "") + (right?.description ?? "")
}
init(_ data: Int) {
self.data = data
}
func insert(_ data: Int) {
if (data < self.data){
if let lhs = left {
lhs.insert(data)
}
else {
let lhNode = Node(data)
lhNode.parent = self
left = lhNode
}
}
else {
if let rhs = right {
rhs.insert(data)
}
else {
let rhNode = Node(data)
rhNode.parent = self
right = rhNode
}
}
}
}
inorderSearch is:
func inorderSearch (_ node: Node, _ data: Int) -> Node? {
if (node.data == data) {return node}
else {
if let lft = node.left {
return inorderSearch(lft, data)
}
if let rht = node.right {
return inorderSearch(rht, data)
}
}
return nil
}
And I insert the nodes as follows:
let gfg = Node(20)
gfg.insert(8)
gfg.insert(4)
gfg.insert(12)
gfg.insert(10)
gfg.insert(14)
gfg.insert(22)
print (gfg)
inorderSucc(inorderSearch(gfg, 8))
inorderSucc(inorderSearch(gfg, 10))
inorderSucc(inorderSearch(gfg, 14))
With the last three lines returning 10, nil and nil respectively. What's going wrong?
The issue stems from your search function. Think of what's happening if it doesn't find the actual number on the leftmost branch (child node(s) of the left node of the left node etc. ... of the root node). A possible correction would be to check for nil while exploring the left hand side, and then proceed to the right hand side of the subgraph as well.
func inorderSearch (_ node: Node, _ data: Int) -> Node? {
if (node.data == data) {return node}
else {
if let lft = node.left, let found = inorderSearch(lft, data) {
return found
} else if let rht = node.right, let found = inorderSearch(rht, data) {
return found
} else {
return nil
}
}
}
This code suppose that you don't have any preconception of what kind of graph this is. Otherwise, you could also check if the searched number is greater or lesser than your current node's value, and search in the left side or the right side accordingly.
You can do it like this:
First, declare class Node like so:
class Node {
let value: Int
var leftChield: Node?
var rightChield: Node?
init(value: Int, leftChield: Node?, rightChield: Node?) {
self.value = value
self.leftChield = leftChield
self.rightChield = rightChield
}
}
Then create all branches:
//Left Branch
let tenNode = Node(value: 10, leftChield: nil, rightChield: nil)
let fourteenNode = Node(value: 14, leftChield: nil, rightChield: nil)
let twelveNode = Node(value: 12, leftChield: tenNode, rightChield: fourteenNode)
let foureNode = Node(value: 4, leftChield: nil, rightChield: nil)
let eithNode = Node(value: 8, leftChield: foureNode, rightChield: twelveNode)
//Right Branch
let twentytwoNode = Node(value: 22, leftChield: nil, rightChield: nil)
// Root Node
let rootTwentyNode = Node(value: 20, leftChield: eithNode, rightChield: twentytwoNode)
Then create a function with logic:
func binarySearch(node: Node?, searchValue: Int) -> Bool {
if node == nil {
return false
}
if node?.value == searchValue {
return true
} else if searchValue < node!.value {
return binarySearch(node: node?.leftChield, searchValue: searchValue)
} else {
return binarySearch(node: node?.rightChield, searchValue: searchValue)
}
}
On the end, call the function like so and add rootNode with a value you want.
binarySearch(node: rootNode, searchValue: 50)

Nilling out optional not working in BST implementation

I am implementing a BST and working on the remove() function, problem is when I try to nil out the node to remove i.e. current, it still exists when I print the trees structure.
class Node<T : Comparable> {
var value: T
var left: Node<T>?
var right: Node<T>?
init(_ value:T) {
self.value = value
}
}
func remove(_ value:T) {
var current: Node<T>? = root
while let root = current {
if value == root.value {
if let _ = root.left, let right = root.right {
let minValue = getMinValue(right)
root.value = minValue
remove(minValue)
} else if let left = root.left {
root.value = left.value
root.left = nil
} else if let right = root.right {
root.value = right.value
root.left = nil
} else {
//This doesn't remove the reference completely
current = nil
}
} else if value > root.value {
current = root.right
} else {
current = root.left
}
}
}
My print function still prints out the node I removed in the previous function
private func printTree(_ node:Node<T>?){
guard let root = node else {
return
}
print(root.value)
printTree(root.right)
printTree(root.left)
}
Unfortunately you just set the local variable current to nil. The parent node of current still has a reference of the node you are trying to remove.