public class LinkedListNode<T>{
var data: T //Data could not be nil.
var previous: LinkedListNode?//The pointer to previous node.
var next: LinkedListNode?//The pointer to next node.init(_ data: T){self.data = data
}}
public enum ErrorStatus {caseError(message: String)case OK
}
public class DoubleLinkedList<T>{
public typealias Node = LinkedListNode<T>
private var head: Node?//Head node of link list.
public var isEmpty: Bool {//If link list has no data, return true.return head == nil
}
public var first: Node?{//Get first node is the head of link list.return head
}
public var last: Node?{//Last node of link list....return node
}
public var count: Int {//Retrun link list's nodes count....return count
}
public func node(atIndex index: Int)-> Node?{//Get node with index...return node
}
public func appendData(data: T){//Append data to link list tail...}
public func insert(data: T, atIndex index: Int)-> ErrorStatus {//Insert data at index
guard index >=0, index <= count else{return ErrorStatus.Error(message:"Index is out of range!")}
let newNode =Node(data)if index ==0{if let node = first {
head = newNode
newNode.next = node
node.previous = newNode
}else{
head = newNode
}}else{
let node =self.node(atIndex: index-1)
let nextNode =self.node(atIndex: index)
node?.next = newNode
newNode.previous = node
newNode.next = nextNode
nextNode?.previous = newNode
}return ErrorStatus.OK
}
public func remove(atIndex index: Int)->(T?, ErrorStatus){//Remove node at index
guard !isEmpty else{return(nil, ErrorStatus.Error(message:"Link list is Empty!"))}
guard index >=0, index < count else{return(nil, ErrorStatus.Error(message:"Index is out of range!"))}
let node =self.node(atIndex: index)
let nextNode =self.node(atIndex: index+1)if index ==0{
head = nextNode
}else{
let beforeNode =self.node(atIndex: index-1)
beforeNode?.next = nextNode
nextNode?.previous = beforeNode
}return(node?.data, ErrorStatus.OK)}}
insert操作:无论insert还是remove都是先拆链,然后再组合成新的数据链。 ① 先判断需要插入数据的index是否在[0, count]的范围之内,注意这里是方括号,也就是包含边界,因为线性表最前面和最后面都可以插入新的数据; ② 生成新节点; ③ 因为这里的双向链表没有采取头节点的方式实现,所以,插入第一个节点和其他节点有点不一样,需要做一些判断; ④ 如果是插入第一个节点,则判断如果该链表为空,则直接设置head=newNode;如果该链表不为空,则将一个节点赋值给node,然后将newNode赋值给head,接着将node赋值给newNode.next,最后设置node.previous=newNode; ⑤ 如果不是插入一个节点,则先获取下标为index-1的节点node,然后获取下标为index的节点nextNode。设置node.next=newNode,然后newNode.next=nextNode,连成一条指向下一个数据元素的链,最后设置newNode.previous=node和nextNode.previous=newNode连上指向上一个数据元素的链,自此,先的数据插入成功;
public func insert(data: T, atIndex index: Int)-> ErrorStatus {//Insert data at index
guard index >=0, index <= count else{return ErrorStatus.Error(message:"Index is out of range!")}
let newNode =Node(data)if index ==0{if let node = first {
head = newNode
newNode.next = node
node.previous = newNode
}else{
head = newNode
}}else{
let node =self.node(atIndex: index-1)
let nextNode =self.node(atIndex: index)
node?.next = newNode
newNode.next = nextNode
newNode.previous = node
nextNode?.previous = newNode
}return ErrorStatus.OK
}
remove操作: ① 先判断是否是空链,如果是则返回,否则再判断需要删除数据的小表是否在合理范围内,如果不是则返回; ② 判断index是否等于0,如果是,则直接将head=secondNode; ③ 获取beforeNode和nextNode,然后将beforeNode.next=nextNode,nextNode,previous=beforeNode,自此,下标为index的节点,没有任何对象指向它,在当前函数域外就外被系统回收掉;
public func remove(atIndex index: Int)->(T?, ErrorStatus){//Remove node at index
guard !isEmpty else{return(nil, ErrorStatus.Error(message:"Link list is Empty!"))}
guard index >=0, index < count else{return(nil, ErrorStatus.Error(message:"Index is out of range!"))}
let node =self.node(atIndex: index)
let nextNode =self.node(atIndex: index+1)if index ==0{
head = nextNode
}else{
let beforeNode =self.node(atIndex: index-1)
beforeNode?.next = nextNode
nextNode?.previous = beforeNode
}return(node?.data, ErrorStatus.OK)}