Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class SafeLinkedList<T: Equatable> {
- // MARK: Linked List's Node Class Declaration
- public class Node {
- var value:T
- var next:Node?
- weak var previous:Node?
- init(_ value: T) {
- self.value = value
- }
- deinit {
- print("xoa \(String(describing: value)) roi nha")
- }
- }
- private var count = 0
- private var head: Node?
- private var last: Node?
- // MARK: Constructor
- public init() {
- }
- public init(_ value: T) {
- add(value)
- }
- public init(_ array: [T]) {
- addAll(array)
- }
- public init(_ array: T...) {
- addAll(array)
- }
- public init(_ list: SafeLinkedList) {
- addAll(list)
- }
- }
- // MARK: add
- extension SafeLinkedList {
- public func add(_ value: T) {
- let newNode = Node(value)
- add(newNode)
- }
- public func add(_ node: Node) {
- let newNode = node
- if let lastNode = last {
- newNode.previous = lastNode
- lastNode.next = newNode
- } else {
- head = newNode
- }
- last = newNode
- count += 1
- }
- public func addFirst(_ value: T) {
- let newNode = Node(value)
- addFirst(newNode)
- }
- public func addFirst(_ node: Node) {
- let newNode = node
- if let headNode = head {
- headNode.previous = newNode
- newNode.next = headNode
- }
- head = newNode
- count += 1
- }
- public func addAll(_ array: [T]) {
- array.forEach { add($0) }
- }
- public func addAll(_ array: T...) {
- array.forEach { add($0) }
- }
- public func addAll(_ list: SafeLinkedList) {
- var nodeToCopy = list.head
- while let node = nodeToCopy {
- add(node.value)
- nodeToCopy = node.next
- }
- }
- public func add(_ value: T, atIndex index: Int) {
- let newNode = Node(value)
- add(newNode, atIndex: index)
- }
- public func add(_ node: Node, atIndex index: Int) {
- if index <= 0 {
- addFirst(node)
- } else if index >= count {
- add(node)
- } else {
- let prev = _node(atIndex: index - 1)!
- let next = prev.next
- node.previous = prev
- node.next = next
- next?.previous = node
- prev.next = node
- }
- }
- }
- // MARK: remove
- extension SafeLinkedList {
- public func removeAll() -> Int {
- let n = count
- head = nil
- last = nil
- count = 0
- return n
- }
- public func remove(_ node: Node) {
- if count == 0 {
- return
- }
- let prev = node.previous
- let next = node.next
- if let prev = prev {
- prev.next = next
- } else {
- head = next
- }
- if let next = next {
- next.previous = prev
- } else {
- last = prev
- }
- node.previous = nil
- node.next = nil
- count -= 1
- }
- public func removeLast() -> Int {
- if last == nil {
- return 0
- }
- remove(last!)
- return 1
- }
- public func removeFirst() -> Int {
- if head == nil {
- return 0
- }
- remove(head!)
- return 1
- }
- public func remove(atIndex index: Int) -> Int {
- if (index < 0 || index >= count) {
- return 0
- }
- if index == 0 {
- return removeFirst()
- }
- if index == count - 1 {
- return removeLast()
- }
- let node = _node(atIndex: index)
- remove(node!)
- return 1
- }
- public func remove(_ value: T) -> Int {
- var node = head
- while let nd = node {
- if nd.value == value {
- remove(nd)
- return 1
- }
- node = nd.next
- }
- return 0
- }
- public func remove(_ array: [T]) -> Int {
- var c = 0
- for v in array {
- c += remove(v)
- }
- return c
- }
- public func remove(_ array: T...) -> Int {
- var c = 0
- for v in array {
- c += remove(v)
- }
- return c
- }
- public func remove(_ list: SafeLinkedList) -> Int {
- var nodeToCopy = list.head
- var c = 0
- while let node = nodeToCopy {
- c += remove(node.value)
- nodeToCopy = node.next
- }
- return c
- }
- }
- // MARK: subscript
- extension SafeLinkedList {
- public subscript(index: Int) -> T? {
- get {
- let node = _node(atIndex: index)
- return node?.value
- }
- set {
- let node = _node(atIndex: index)
- if let node = node {
- node.value = newValue!
- }
- }
- }
- public func objects(from: Int, to: Int) -> [T] {
- var objs = [T]()
- var nodeToCopy = head
- var i = 0
- while let node = nodeToCopy {
- if (i > to) {
- break
- }
- if (i >= from && i <= to) {
- objs.append(node.value)
- }
- nodeToCopy = node.next
- i += 1
- }
- return objs
- }
- public subscript(bounds: CountableRange<Int>) -> [T] {
- return self.objects(from: bounds.lowerBound, to: bounds.upperBound - 1)
- }
- public subscript(bounds: CountableClosedRange<Int>) -> [T] {
- return self.objects(from: bounds.lowerBound, to: bounds.upperBound)
- }
- public subscript(bounds: CountablePartialRangeFrom<Int>) -> [T] {
- return self.objects(from: bounds.lowerBound, to: count - 1)
- }
- public subscript(bounds: PartialRangeThrough<Int>) -> [T] {
- return self.objects(from: 0, to: bounds.upperBound)
- }
- public subscript(bounds: PartialRangeUpTo<Int>) -> [T] {
- return self.objects(from: 0, to: bounds.upperBound - 1)
- }
- }
- // MARK: get
- extension SafeLinkedList {
- public func _node(atIndex index: Int) -> Node? {
- if index < 0 || index >= count {
- return nil
- }
- if index == 0 {
- return head!
- } else {
- var node = head!.next
- for _ in 1..<index {
- node = node?.next
- if node == nil {
- break
- }
- }
- return node!
- }
- }
- public func firstObject() -> T? {
- return head?.value
- }
- public func lastObject() -> T? {
- return last?.value
- }
- public func object(atIndex index: Int) -> T? {
- return self[index]
- }
- public func object(inBound bounds:CountableRange<Int>) -> [T] {
- return self[bounds]
- }
- public func object(inBound bounds:CountableClosedRange<Int>) -> [T] {
- return self[bounds]
- }
- public func object(inBound bounds:CountablePartialRangeFrom<Int>) -> [T] {
- return self[bounds]
- }
- public func object(inBound bounds:PartialRangeThrough<Int>) -> [T] {
- return self[bounds]
- }
- public func object(inBound bounds:PartialRangeUpTo<Int>) -> [T] {
- return self[bounds]
- }
- public func size() -> Int {
- return count
- }
- }
- // MARK: convert
- extension SafeLinkedList {
- public func toArray() -> [T] {
- var arr = [T]()
- var nodeToCopy = head
- while let node = nodeToCopy {
- arr.append(node.value)
- nodeToCopy = node.next
- }
- return arr
- }
- public func toReversedArray() -> [T] {
- var arr = [T]()
- var nodeToCopy = last
- while let node = nodeToCopy {
- arr.append(node.value)
- nodeToCopy = node.previous
- }
- return arr
- }
- public func clone() -> SafeLinkedList {
- return SafeLinkedList<T>(self)
- }
- }
- // MARK: Sequence Conformance
- extension SafeLinkedList: Sequence {
- public __consuming func makeIterator() -> Iterator {
- return Iterator(node: head)
- }
- public struct Iterator: IteratorProtocol {
- private var currentNode: Node?
- fileprivate init(node: Node?) {
- currentNode = node
- }
- public mutating func next() -> T? {
- guard let node = currentNode else {
- return nil
- }
- currentNode = node.next
- return node.value
- }
- }
- }
- // MARK: - operator
- extension SafeLinkedList {
- public static func -(lhs: SafeLinkedList, rhs: SafeLinkedList) -> SafeLinkedList {
- var clone = lhs.clone()
- clone.remove(rhs)
- return clone
- }
- public static func -=(lhs: SafeLinkedList, rhs: SafeLinkedList) -> SafeLinkedList {
- lhs.remove(rhs)
- return lhs
- }
- public static func -=(lhs: SafeLinkedList, rhs: T) -> SafeLinkedList {
- lhs.remove(rhs)
- return lhs
- }
- public static func +(lhs: SafeLinkedList, rhs: SafeLinkedList) -> SafeLinkedList {
- var clone = lhs.clone()
- clone.addAll(rhs)
- return clone
- }
- public static func +=(lhs: SafeLinkedList, rhs: SafeLinkedList) -> SafeLinkedList {
- lhs.addAll(rhs)
- return lhs
- }
- public static func +=(lhs: SafeLinkedList, rhs: T) -> SafeLinkedList {
- lhs.add(rhs)
- return lhs
- }
- public static func ==(lhs: SafeLinkedList, rhs: SafeLinkedList) -> Bool {
- if lhs.size() != rhs.size() {
- return false
- }
- var lhsNode = lhs.head
- var rhsNode = rhs.head
- while lhsNode != nil {
- if lhsNode!.value != rhsNode!.value {
- return false
- }
- lhsNode = lhsNode!.next
- rhsNode = rhsNode!.next
- }
- return true
- }
- }
- // MARK: - Extension to enable the standard conversion of a list to String
- extension SafeLinkedList: CustomStringConvertible {
- public var description: String {
- var s = "["
- var node = head
- while let nd = node {
- s += "\(nd.value)"
- node = nd.next
- if node != nil { s += ", " }
- }
- return s + "]"
- }
- }
- /*
- var n: Int = 0
- var x: String?
- var array: [String]?
- let a = SafeLinkedList<String>()
- let b = SafeLinkedList<String>("1")
- let c = SafeLinkedList<String>(["0", "1", "2", "3", "5", "6"])
- let d = SafeLinkedList<String>("a", "b", "c", "d", "e", "f")
- a.add("A")
- b.addFirst("0")
- c.add("4", atIndex: 4)
- c.add("-1", atIndex: -10)
- c.add("999", atIndex: 999)
- d.addAll(["g", "h"])
- d.addAll("i", "j")
- a.addAll(b)
- print("a = \(a)")
- print("b = \(b)")
- print("c = \(c)")
- print("d = \(d)")
- print("before remove all: a = \(a)")
- n = a.removeAll()
- print("after remove all: a = \(a)")
- print("n = \(n)")
- a.add("a")
- print("before remove last: a = \(a)")
- n = a.removeLast()
- print("after remove last: a = \(a)")
- print("n = \(n)")
- a.add("a")
- print("before remove first: a = \(a)")
- n = a.removeFirst()
- print("after remove first: a = \(a)")
- print("n = \(n)")
- print("before remove last: c = \(c)")
- n = c.removeLast()
- print("after remove last: c = \(c)")
- print("n = \(n)")
- print("before remove first: c = \(c)")
- n = c.removeFirst()
- print("after remove first: c = \(c)")
- print("n = \(n)")
- print("before remove atIndex 1: d = \(d)")
- n = d.remove(atIndex: 1)
- print("after remove atIndex 1: d = \(d)")
- print("n = \(n)")
- print("before remove atIndex '3': c = \(c)")
- n = c.remove("3")
- print("after remove atIndex '3': c = \(c)")
- print("n = \(n)")
- print("before remove 'c', 'h', 'j': d = \(d)")
- n = d.remove(["c", "h", "j"])
- print("after remove remove 'c', 'h', 'j': d = \(d)")
- print("n = \(n)")
- print("before remove '2', '4': c = \(c)")
- n = c.remove("2", "4")
- print("after remove '2', '4': c = \(c)")
- print("n = \(n)")
- print("before remove 'a', 'g', 'c': d = \(d)")
- let e = SafeLinkedList<String>("a", "g", "c")
- n = d.remove(e)
- print("after remove remove 'a', 'g', 'c': d = \(d)")
- print("n = \(n)")
- print("c[-69] = \(c[-69])")
- print("c[96] = \(c[96])")
- x = c[2]
- print("c[2] = \(x)")
- print("before c = \(c)")
- c[2] = "22"
- print("after c = \(c)")
- x = c.firstObject()
- print("c first = \(x)")
- x = c.lastObject()
- print("c last = \(x)")
- x = c.object(atIndex: 2)
- print("c[2] = \(x)")
- array = c[1...3]
- print("c[1...3] = \(array)")
- array = c.object(inBound: 1...3)
- print("c[1...3] = \(array)")
- n = d.size()
- print("d.size() = \(n)")
- for item in d {
- print(item)
- }
- array = d.toArray()
- dump(array)
- array = d.toReversedArray()
- dump(array)
- print("d contain 'e': \(d.contains("e"))")
- print("d contain 'a': \(d.contains("a"))")
- print("clone")
- let f = SafeLinkedList<String>("a", "b", "c", "d", "e", "f")
- let g = f.clone()
- print(f)
- print(g)
- f.removeAll()
- print(f)
- print(g)
- print("compare")
- let c1 = SafeLinkedList<String>("a", "b", "c", "d", "e", "f")
- let c2 = SafeLinkedList<String>("a", "b", "c", "d", "e", "g")
- print("c1 == g : \(c1 == g)")
- print("c1 == f : \(c1 == f)")
- print("c1 == c2 : \(c1 == c2)")
- let c3 = c1 + c2
- print(c1)
- print(c3)
- c1 += "xxx"
- print(c1)
- let c4 = c3 - c1
- print(c3)
- print(c1)
- print(c4)
- let c5 = SafeLinkedList<String>("k", "l", "c", "d", "m", "n")
- c3 -= c5
- print(c5)
- print(c3)
- c5 -= "k"
- print(c5)
- */
Add Comment
Please, Sign In to add comment