Skip to content

Commit

Permalink
queue class (FIFO)
Browse files Browse the repository at this point in the history
Implement FIFO queue class with single linked list class
  • Loading branch information
zhaohuixing committed Feb 8, 2019
1 parent 2b49123 commit 8a0be3f
Show file tree
Hide file tree
Showing 15 changed files with 473 additions and 11 deletions.
24 changes: 24 additions & 0 deletions Queue.playground/Contents.swift
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())

}
70 changes: 70 additions & 0 deletions Queue.playground/Sources/CQueue.swift
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
}
}
182 changes: 182 additions & 0 deletions Queue.playground/Sources/CSingleLList.swift
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
}

}
}

120 changes: 120 additions & 0 deletions Queue.playground/Sources/SingleLLNode.swift
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);
}
}


Loading

0 comments on commit 8a0be3f

Please sign in to comment.