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 indexguard 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 = newNodenewNode.next = nodenode.previous = newNode}else{head = newNode}}else{let node =self.node(atIndex: index-1)let nextNode =self.node(atIndex: index)node?.next = newNodenewNode.previous = nodenewNode.next = nextNodenextNode?.previous = newNode}return ErrorStatus.OK}public func remove(atIndex index: Int)->(T?, ErrorStatus){//Remove node at indexguard !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 = nextNodenextNode?.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 indexguard 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 = newNodenewNode.next = nodenode.previous = newNode}else{head = newNode}}else{let node =self.node(atIndex: index-1)let nextNode =self.node(atIndex: index)node?.next = newNodenewNode.next = nextNodenewNode.previous = nodenextNode?.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 indexguard !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 = nextNodenextNode?.previous = beforeNode}return(node?.data, ErrorStatus.OK)}