Thinking--從尾到頭打印鏈表

Thinking系列,旨在利用10分鐘的時間傳達一種可落地的編程思想。

使用 typescript 生成鏈表

interface node<T> {
    next: node<T> | null
    element: T
}

class LinkedNode<T> implements node<T> {
    element: T
    next: node<T> | null = null
    constructor(element: T, next: node<T> | null = null) {
        this.element = element
        this.next = next
    }
}

class LinkedList<T> {
    length: number = 0
    head: node<T> | null = null
    append(element: node<T>) {
        let node: node<T> = element
        if (this.head === null) {
            this.head = node
        } else {
          	// 不改變head指針
            let current = this.head
            while (current.next) {
                current = current.next
            }
            current.next = node
        }
        this.length++
    }
}

需求: 如,鏈表信息{"length":3,"head":{"next":{"next":{"next":null,"element":"c"},"element":"b"},"element":"a"}},鏈表倒序輸出c b a

var testLinkedList = new LinkedList<string>()
testLinkedList.append(new LinkedNode<string>('a'))
testLinkedList.append(new LinkedNode<string>('b'))
testLinkedList.append(new LinkedNode<string>('c'))

常規思路

循環保存,然後倒序輸出

function printLinkedListReversing (head: node<string>): void {
    let result: string[] = []
    while(head !== null) {
        result.push(head.element)
        head = head.next
    }
    console.log(result.reverse())
}    

延伸

倒敘輸出(先進後出 FILO),典型的棧。
依靠遞歸(遞歸本質上是一個棧結構)

function printLinkedListReversing_recursion(head: node<string>): void{
    if (head !== null) {
        if (head.next != null) {
            printLinkedListReversing_recursion(head.next)
        }
        console.log(head.element)
    }
}

需要注意的是,當鏈表過長時,會導致函數調用的層級過深,可能導致調用棧溢出。

擴展: 數組存儲中間狀態

function printLinkedListReversing(head: node<string>, result: Array<string> = []): Array<string> {
    if (head !== null) {
        if (head.next != null) {
            printLinkedListReversing(head.next, result)
        }
      	console.log(head.element)
        result.push(head.element)
    }
    return result
}

console.log(printLinkedListReversing(testLinkedList.head, []))	// [ 'c', 'b', 'a' ]

物理結構:

  • 順序存儲結構:數組
  • 鏈式存儲結構:鏈表

邏輯結構:

  • 線性結構:順序表、棧、隊列
  • 非線性結構:樹、圖
    在這裏插入圖片描述
    數組:讀操作多、寫操作少的場景。 非常高效的隨機訪問能力;插入和刪除元素效率不高。
    鏈表:靈活地進行插入和刪除操作。
查找 更新 插入 刪除
數組 O(1) O(1) O(n) O(n)
鏈表 O(n) O(1) O(1) O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章