003 - 鏈表的實現(xiàn)

1.鏈表
  • 鏈表是一種鏈式存儲的線性表,所有元素的內存地址不一定是連續(xù)的
  • 鏈表可以用到多少申請多少,不浪費內存空間
  • 鏈表中通常包含元素和下一個節(jié)點的地址
  • 鏈表的尾結點中的下一個節(jié)點的地址為空
2.鏈表接口設計
  • isEmpty:是否為空
  • push:從head處添加
  • append:從tail處添加
  • insert(after:)指定位置添加
  • pop:從表頭刪除
  • removeLast:從結尾刪除
  • remove(after:)任意位置刪除
  • removeAll:清除所有元素
  • getNode(index:)根據(jù)下標獲取到節(jié)點
  • reverseNode()翻轉鏈表
2.鏈表swift實現(xiàn)
import Foundation

public class Node<Value>: 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<Value> {
    public var node: Node<Value>?
    public var size: Int = 0
    public var head: Node<Value>?
    public var tail: Node<Value>?
    public var next: NodeList?
    public var value: Value?
    public init() {}

}

extension NodeList: CustomStringConvertible {
    /// 是否為空
    public func isEmpty() -> Bool {
        return head == nil
    }
   
    /// 從head處添加
    // 思路:創(chuàng)建新的head,并把之前的head設置為新head的next 
    public func push(_ value: Value) {
        head = Node(value: value, next: head)
        if tail == nil {
            tail = head
        }
        size += 1
    }

    /// 從tail處添加
    // 思路:創(chuàng)建新的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.創(chuàng)建新Node,并且新node的next指向index所在的node 3.index-1所在的node的next指向新創(chuàng)建的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
        }
    }
    
    /// 從結尾刪除
    // 思路:倒數(shù)第二個node的next置空
    // 如何獲取倒數(shù)第二個node 方式1 getNode取  方式2:兩個node,一個是pre 一個是cur,從頭循環(huán)遍歷,直到cur.next == nil為止,此時的pre就是倒數(shù)第二個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,從頭循環(huán)遍歷,直到cur.next == nil為止,此時的pre就是倒數(shù)第二個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
    }
    
    /// 根據(jù)下標獲取到節(jié)點
    public func getNode(_ index: Int) -> Node<Value>?{
   
        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)
    }
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容