-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement FIFO queue class with single linked list class
- Loading branch information
1 parent
2b49123
commit 8a0be3f
Showing
15 changed files
with
473 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
|
||
typealias CQueueInt = CQueue<Int> | ||
|
||
let testQ : CQueueInt = CQueueInt() | ||
|
||
testQ.Push_Back(value: 1) | ||
testQ.Push_Back(value: 2) | ||
testQ.Push_Back(value: 3) | ||
testQ.Push_Back(value: 4) | ||
testQ.Push_Back(value: 5) | ||
testQ.Push_Back(value: 6) | ||
testQ.Push_Back(value: 7) | ||
testQ.Push_Back(value: 8) | ||
|
||
print(testQ.Count()) | ||
|
||
while testQ.Empty() == false { | ||
let v = testQ.Front() | ||
print(v ?? "v is nil") | ||
let v2 = testQ.Pop_Front() | ||
print(v2 ?? "v2 is nil") | ||
print(testQ.Count()) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// | ||
// CQueue.swift | ||
// A queue class implemented by single linkedin list class CSingleList | ||
// | ||
// Created by Zhaohui Xing on 02/06/19. | ||
// Copyright © 2019 Zhaohui Xing. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
public class CQueue<T : Equatable> { | ||
let m_Container: CSingleLinkedList<T> | ||
|
||
//Make default initializer public to be accessible | ||
public init() { | ||
m_Container = CSingleLinkedList() | ||
} | ||
} | ||
|
||
extension CQueue { | ||
public func Push_Back(value: T) { | ||
let newNode : CSingleLinkedListNode<T> = CSingleLinkedListNode<T>(data:value) | ||
m_Container.Append(value: newNode) | ||
} | ||
} | ||
|
||
extension CQueue { | ||
public func Pop_Front()->T? { | ||
var tempValue : T? | ||
tempValue = nil | ||
|
||
if m_Container.head != nil { | ||
tempValue = m_Container.head?.data | ||
m_Container.RemoveHead() | ||
} | ||
|
||
return tempValue | ||
} | ||
} | ||
|
||
extension CQueue { | ||
public func Front()->T? { | ||
var tempValue : T? | ||
tempValue = nil | ||
|
||
if m_Container.head != nil { | ||
tempValue = m_Container.head?.data | ||
} | ||
|
||
return tempValue | ||
} | ||
} | ||
|
||
extension CQueue { | ||
public func Empty()->Bool { | ||
var ret : Bool = true | ||
|
||
if m_Container.head != nil { | ||
ret = false | ||
} | ||
return ret | ||
} | ||
} | ||
|
||
extension CQueue { | ||
public func Count()->Int { | ||
let ret : Int = m_Container.count | ||
return ret | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
// | ||
// CSingleLList.swift | ||
// LinkList | ||
// | ||
// Created by Zhaohui Xing on 10/26/18. | ||
// Copyright © 2018 Zhaohui Xing. All rights reserved. | ||
// | ||
import Foundation | ||
|
||
//class base sll as reference type | ||
public class CSingleLinkedList<T : Equatable> { //Equatable for ! operator in line#60 | ||
var m_Head: CSingleLinkedListNode<T>? | ||
var m_Tail: CSingleLinkedListNode<T>? | ||
|
||
init() { | ||
} | ||
|
||
public init(head: CSingleLinkedListNode<T>) { | ||
self.m_Head = head | ||
self.m_Tail = self.m_Head?.tail | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public var head : CSingleLinkedListNode<T>? { | ||
get { | ||
return m_Head | ||
} | ||
set (newNode) { | ||
m_Head = newNode; | ||
m_Tail = newNode?.tail | ||
} | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public var tail : CSingleLinkedListNode<T>? { | ||
return m_Tail | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public var count : Int { | ||
var nCount : Int = 0 | ||
var cur : CSingleLinkedListNode<T>? = m_Head | ||
|
||
while cur != nil { | ||
cur = cur?.next | ||
nCount += 1 | ||
} | ||
|
||
return nCount | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public subscript (value : T) -> CSingleLinkedListNode<T>? { | ||
var cur : CSingleLinkedListNode<T>? = m_Head | ||
|
||
while cur != nil && cur!.data != value { | ||
cur = cur?.next | ||
} | ||
|
||
return cur | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public func reverse() { | ||
let prev : CSingleLinkedListNode<T>? = CSingleLinkedListNode<T>(); //This avoid the tail node is nil and while loop cannot go through all nodes | ||
prev?.next = m_Head //prev.next as temperory head shifting cursor | ||
let cur : CSingleLinkedListNode<T>? = m_Head //Using cur.next as moving cursor, Note: this approach the orginal head's next is altered after the loop | ||
|
||
while cur?.next != nil { | ||
let temp: CSingleLinkedListNode<T>? = cur?.next | ||
cur?.next = temp?.next; | ||
temp?.next = prev?.next | ||
prev?.next = temp | ||
} | ||
m_Head = prev?.next | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public func reverse2() { | ||
let prev : CSingleLinkedListNode<T>? = CSingleLinkedListNode<T>(); //This avoid the tail node is nil and while loop cannot go through all nodes | ||
prev?.next = m_Head //prev.next as temperory head shifting cursor | ||
var cur : CSingleLinkedListNode<T>? = m_Head?.next //Using cur as moving cursor | ||
|
||
while cur != nil { | ||
let temp: CSingleLinkedListNode<T>? = cur | ||
cur = temp?.next; | ||
temp?.next = prev?.next | ||
prev?.next = temp | ||
} | ||
m_Head?.next = nil; //This one need this call, since using cur as moving cursor and orginal head.next is not altered | ||
m_Head = prev?.next | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public func iscycled()->(retFlag : Bool, cycleNode:CSingleLinkedListNode<T>?, tailNode:CSingleLinkedListNode<T>?) { | ||
var bRet : (retFlag : Bool, cycleNode:CSingleLinkedListNode<T>?, tailNode:CSingleLinkedListNode<T>?) = (false, nil, nil) | ||
|
||
if m_Head != nil { | ||
bRet = m_Head!.iscycled() | ||
} | ||
|
||
return bRet | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public func AddHead(head: CSingleLinkedListNode<T>) { | ||
head.next = m_Head; | ||
m_Head = head; | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public func RemoveHead() { | ||
m_Head = m_Head?.next; | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public func Append(value: CSingleLinkedListNode<T>) { | ||
if self.head == nil { | ||
self.head = value | ||
} | ||
else { | ||
m_Tail?.next = value | ||
m_Tail = value | ||
} | ||
} | ||
} | ||
|
||
extension CSingleLinkedList { | ||
public func reverseBetween(start startIndex: Int, end endIndex: Int) { | ||
if endIndex <= startIndex { | ||
return | ||
} | ||
|
||
var cur : CSingleLinkedListNode<T>? = m_Head | ||
|
||
//tempPrev is the start node to swap sequence. | ||
var tempPrev : CSingleLinkedListNode<T>? //"?" allowing following calling "tempPrev = nil", otherwise compiling error for it | ||
tempPrev = nil | ||
|
||
let steps : Int = (0 < startIndex) ? startIndex-1 : 0 | ||
for _ in 0...steps { | ||
if cur != nil { | ||
tempPrev = cur | ||
cur = cur?.next; | ||
} | ||
} | ||
if cur == nil { | ||
return | ||
} | ||
|
||
var tempHead: CSingleLinkedListNode<T>? = cur; | ||
|
||
|
||
for _ in startIndex...(endIndex-1) { | ||
if cur?.next != nil { | ||
let temp: CSingleLinkedListNode<T>? = cur?.next | ||
cur?.next = temp?.next; | ||
temp?.next = tempHead | ||
tempHead = temp | ||
} | ||
} | ||
|
||
if tempPrev != nil { | ||
tempPrev?.next = tempHead | ||
} | ||
else { | ||
m_Head = tempHead | ||
} | ||
|
||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// | ||
// SingleLList.swift | ||
// LinkList | ||
// | ||
// Created by Zhaohui Xing on 10/26/18. | ||
// Copyright © 2018 Zhaohui Xing. All rights reserved. | ||
// | ||
import Foundation | ||
|
||
public class CSingleLinkedListNode<T> { | ||
var m_Data: T? | ||
var m_Next: CSingleLinkedListNode<T>? | ||
var m_Hashvalue : Int64 //The hash value for hash table | ||
init() { | ||
let m : Int64 = Int64(INT_MAX) | ||
let v1 : Int64 = Int64.random(in: 0 ..< m) | ||
let v2 : Int64 = Int64.random(in: 0 ..< m) | ||
|
||
m_Hashvalue = v1 ^ v2 | ||
} | ||
|
||
public init(data: T) { | ||
let m : Int64 = Int64(INT_MAX) | ||
let v1 : Int64 = Int64.random(in: 0 ..< m) | ||
let v2 : Int64 = Int64.random(in: 0 ..< m) | ||
m_Hashvalue = v1 ^ v2 | ||
|
||
self.m_Data = data | ||
} | ||
|
||
public func clone()-> CSingleLinkedListNode<T> { | ||
let cloneNode : CSingleLinkedListNode<T> = CSingleLinkedListNode<T>(data: self.data!) //reference type "cloneNode", avoid "mutated warning for var" | ||
//cloneNode.next = ((m_Next!) ?? m_Next?.clone() , nil) | ||
/*guard let cloneNode.next = self.m_Next?.clone() else | ||
{ | ||
print("Catched the source next nil") | ||
cloneNode.next = nil | ||
}*/ | ||
if m_Next != nil | ||
{ | ||
cloneNode.next = self.m_Next!.clone() | ||
} | ||
return cloneNode | ||
} | ||
} | ||
|
||
extension CSingleLinkedListNode { | ||
public var data : T? { | ||
return m_Data | ||
} | ||
} | ||
|
||
extension CSingleLinkedListNode { | ||
public var next : CSingleLinkedListNode<T>? { | ||
set (newNode) { | ||
m_Next = newNode | ||
} | ||
get { | ||
return m_Next | ||
} | ||
} | ||
} | ||
|
||
extension CSingleLinkedListNode { | ||
public var tail : CSingleLinkedListNode<T>? { | ||
let ret = iscycled() | ||
if ret.retFlag { | ||
return ret.tailNode | ||
} | ||
else { | ||
if m_Next != nil { | ||
if m_Next?.tail != nil { | ||
return m_Next?.tail | ||
} | ||
else { | ||
return m_Next | ||
} | ||
} | ||
else { | ||
return self; | ||
} | ||
} | ||
} | ||
} | ||
|
||
extension CSingleLinkedListNode { //: Hashable { | ||
public var hashValue: Int64 { | ||
return m_Hashvalue | ||
} | ||
} | ||
|
||
|
||
extension CSingleLinkedListNode { | ||
public func iscycled()->(retFlag : Bool, cycleNode:CSingleLinkedListNode?, tailNode:CSingleLinkedListNode?) { | ||
var bRet : Bool = false | ||
var cycleNode:CSingleLinkedListNode? | ||
var tailNode:CSingleLinkedListNode? | ||
|
||
var hashLut = [Int64: CSingleLinkedListNode]() //hash table by Dictionary | ||
var cur : CSingleLinkedListNode<T>? = self; | ||
|
||
cycleNode = nil | ||
tailNode = nil | ||
|
||
while cur != nil { | ||
if cur!.next != nil && hashLut[cur!.next!.hashValue] != nil { | ||
cycleNode = cur!.next! | ||
tailNode = cur! | ||
bRet = true | ||
break | ||
} | ||
hashLut[cur!.hashValue] = cur | ||
cur = cur!.next | ||
} | ||
|
||
return (bRet, cycleNode, tailNode); | ||
} | ||
} | ||
|
||
|
Oops, something went wrong.