003 - 链表的实现

1.链表
  • 链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的
  • 链表可以用到多少申请多少,不浪费内存空间
  • 链表中通常包含元素和下一个节点的地址
  • 链表的尾结点中的下一个节点的地址为空
2.链表接口设计
  • isEmpty:是否为空
  • push:从head处添加
  • append:从tail处添加
  • insert(after:)指定位置添加
  • pop:从表头删除
  • removeLast:从结尾删除
  • remove(after:)任意位置删除
  • removeAll:清除所有元素
  • getNode(index:)根据下标获取到节点
  • reverseNode()翻转链表
2.链表swift实现
import Foundation

public class Node: CustomStringConvertible{
   
    public var value: Value?
    public var next: Node?
    public var size: Int = 0
    public init(value: Value, next: Node? = nil) {
        self.value = value
        self.next = next
    }
    
    // 重写description方法,方便打印
    public var description: String{
        guard let next = next else {
            return "\(value!)"
        }
        return "\(value!) -> " + "\(next)"
    }
    
}


public class NodeList {
    public var node: Node?
    public var size: Int = 0
    public var head: Node?
    public var tail: Node?
    public var next: NodeList?
    public var value: Value?
    public init() {}

}

extension NodeList: CustomStringConvertible {
    /// 是否为空
    public func isEmpty() -> Bool {
        return head == nil
    }
   
    /// 从head处添加
    // 思路:创建新的head,并把之前的head设置为新head的next 
    public func push(_ value: Value) {
        head = Node(value: value, next: head)
        if tail == nil {
            tail = head
        }
        size += 1
    }

    /// 从tail处添加
    // 思路:创建新的tail,并把原来tial的next指向新的tial,新的tial的next为空  最后把新的tail覆盖掉原来的tail
    public func append(_ value: Value){
        // 判断链表为空
        guard !isEmpty() else {
            push(value)
            size += 1
            return
        }
        tail?.next = Node(value: value)
        tail = tail?.next
        size += 1
    }
    /// 指定位置添加
    // 思路:1.获取到index-1的Node 2.创建新Node,并且新node的next指向index所在的node 3.index-1所在的node的next指向新创建的node
    public func insert(_ index: Int, value: Value){
        if index < 1 {
            push(value)
            size += 1
        }else {
            if index > size - 1 {
                append(value)
                size += 1
            }else {
                let preNode = getNode(index - 1)
                preNode?.next = Node(value: value, next: preNode?.next)
                size += 1
            }
        }
    }
    
    /// 从表头删除
    // 思路:head指向第二个node
    public func pop() {
        if isEmpty() {
            print("Empty list")
        }else {
            
            head = head?.next
            size -= 1
        }
    }
    
    /// 从结尾删除
    // 思路:倒数第二个node的next置空
    // 如何获取倒数第二个node 方式1 getNode取  方式2:两个node,一个是pre 一个是cur,从头循环遍历,直到cur.next == nil为止,此时的pre就是倒数第二个node
        // 方式一
//    public func removeLast() {
//        if size == 0 {
//            return
//        }
//        if size == 1{
//            pop()
//        }else{
//
//            let node = getNode(size-2)
//            node?.next = nil
//            tail = node
//            size -= 1
//        }
//    }
    
    // 方式二:两个node,一个是pre 一个是cur,从头循环遍历,直到cur.next == nil为止,此时的pre就是倒数第二个node
    public func removeLast() {
        guard head?.next != nil else {
            pop()
            return
        }
        var pre = head
        var cur = head?.next
        
        while cur?.next != nil {
            cur = cur?.next
            pre = pre?.next
        }
        pre?.next = nil
        tail = pre
        size -= 1
    }
    
    
    /// 任意位置删除
    // 思路:把index-1的next指向index+1的node
    public func remove(_ index: Int) {
        if index < 0 || index > size - 1{
            print("下标输入错误")
           return
        }
        if size == 1 || index == 0 {
            pop()
            return
        }
        if size == 2 {
            if index == 1 {
                head?.next = nil
                size -= 1
                return
            }
        } else {
            let preNode = getNode(index - 1)
            preNode?.next = preNode?.next?.next
            size -= 1
        }
        
    }
    
    /// 清除所有元素
    // 思路: heda置空 size归零
    public func removeAll() {
        head = nil
        size = 0
    }
    
    /// 根据下标获取到节点
    public func getNode(_ index: Int) -> Node?{
   
        var currentNode = head
        var currentIndex: Int = 0
        while currentNode != nil && currentIndex < index {
            currentNode = currentNode?.next
            currentIndex += 1
        }
    
        return currentNode
    }
    
    // 重写description方法,方便打印
    public var description: String{
        guard let head = head else {
            return "Empty list"
        }
        return String(describing: head)
    }
}

你可能感兴趣的:(003 - 链表的实现)