使用 scala 實現雙向鏈表

雙向鏈表也叫雙鏈表。雙向鏈表中不僅有指向後一個節點的指針,還有指向前一個節點的指針。這樣可以從任何一個節點訪問前一個節點,當然也可以訪問後一個節點,以至整個鏈表。
一般是在需要大批量的另外儲存數據在鏈表中的位置的時候用。雙向鏈表也可以
在這裏插入圖片描述

package com.atguigu.datastruc.linked_list

/**
  * Author lzc
  * Date 2019-11-27 11:11
  */
object DoublyLinkedListDemo {
    def main(args: Array[String]): Unit = {
        val list = new DoublyLinkedList[Int]()
        list.add(10)
        list.add(20)
        list.add(30)
        
        list.printInfo()
        list.delete(30)
        list.delete(20)
        list.delete(10)
        list.printInfo()
    }
}

class DoublyLinkedList[T] {
    
    var head: Node = _
    var tail: Node = _
    
    /**
      * 刪除節點
      * 雙向節點刪除比較方便: 支持自刪除
      *
      * @param ele
      */
    def delete(ele: T): Boolean = {
        // 找到要刪除的節點
        val targetNode: Node = find(ele)
        if (targetNode == null) { // 如果要刪除的節點不存在
            false
        }
        else { // 刪除的節點存在
            // 上一個節點
            val preNode: Node = targetNode.pre
            val nextNode: Node = targetNode.next // 下一個節點
            
            if (targetNode == head) { // 如果是頭節點
                if (nextNode != null) nextNode.pre = null // 下一個節點的 pre 指向 null
                head = nextNode // 更新頭節點
            } else if (targetNode == tail) { // 如果是尾節點
                preNode.next = null // 上一個節點的 next 指向 null
                tail = preNode // 更新尾節點
            } else {
                preNode.next = nextNode
                nextNode.pre = preNode
            }
            true
        }
    }
    
    /**
      * 找到要刪除的元素所在的節點
      *
      * @param ele
      */
    protected def find(ele: T): Node = {
        var tmp: Node = head // 從頭節點開始查找
        while (tmp != null) {
            if (tmp.value == ele) return tmp
            tmp = tmp.next
        }
        null
    }
    
    /**
      * 新增節點
      *
      * @param ele
      */
    def add(ele: T): Boolean = {
        val newNode: Node = Node(ele, null, null)
        if (head == null) { // 第一次添加
            head = newNode // 因爲第一個元素, 上一個和下一個節點都應該是 null
            
        } else { // 不是第一次添加, tail 的next節點指向新節點, 新節點的pre節點指向 tail
            tail.next = newNode
            newNode.pre = tail
        }
        // 更新 tail 的指向
        tail = newNode
        true
    }
    
    
    /**
      * 打印鏈表的元素
      */
    def printInfo(): Unit = {
        if (head == null) return
        
        var tmp: Node = head
        do {
            print(tmp.value + "->")
            tmp = tmp.next
        } while (tmp != null)
        
        println()
    }
    
    case class Node(value: T, var pre: Node, var next: Node)
    
}
發佈了79 篇原創文章 · 獲贊 375 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章