深入理解鏈表數據結構:從Java LinkedList到自定義實現

引言

鏈表作為基礎數據結構之一,在Java集合框架中以LinkedList的形式提供。本文將深入分析Java原生LinkedList的實現機制,并介紹我自定義實現的MyLinkedList,最后對比兩者的設計差異與實現特點。

Java原生LinkedList解析

基本結構

Java的LinkedList是基于雙向鏈表實現的列表,主要特點包括:

  1. 雙向鏈表結構:每個節點包含前驅和后繼指針

  2. 高效端點操作:頭尾插入/刪除時間復雜度為O(1)

  3. 隊列功能:實現了Deque接口,支持隊列操作

核心實現機制

// JDK中的關鍵字段
transient int size = 0;
transient Node<E> first; // 頭節點
transient Node<E> last;  // 尾節點// 節點定義
private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}
}

插入操作示例

void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;
}

時間復雜度分析

  • 頭尾插入/刪除:O(1)

  • 按索引訪問:平均O(n/2)

  • 中間插入/刪除:O(n)(需要先定位節點)

自定義MyLinkedList實現

package com.zsy;import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;/*** 自定義雙向鏈表實現,支持泛型元素存儲和基本列表操作** <p>本實現提供類似Java LinkedList的核心功能,包括:</p>* <ul>*   <li>基于節點的雙向鏈表結構</li>*   <li>支持頭部和尾部高效操作</li>*   <li>提供元素遍歷功能</li>*   <li>實現基本的增刪改查操作</li>* </ul>** <p><b>特性說明:</b></p>* <ul>*   <li>時間復雜度:訪問O(n),頭尾操作O(1)</li>*   <li>空間復雜度:O(n)</li>*   <li><b>非線程安全</b> - 多線程環境下需要外部同步</li>* </ul>** @param <E> 列表元素類型* @author zsy* @see List*/
public class MyLinkedList<E> implements List<E> {/*** 當前列表中元素的數量*/private int size;/*** 鏈表頭節點*/private Node<E> head;/*** 鏈表尾節點*/private Node<E> tail;/*** 將指定元素追加到列表末尾** @param element 要添加的元素*/@Overridepublic void add(E element) {Node<E> newNode = new Node<>(tail, element, null);if (tail != null) {tail.next = newNode;} else {head = newNode;}tail = newNode;size++;}/*** 在列表的指定位置插入指定元素** @param element 要插入的元素* @param index 插入位置的索引* @throws IndexOutOfBoundsException 如果索引超出范圍*/@Overridepublic void add(E element, int index) {rangeCheckForAdd(index);if (index == size) {add(element);return;}Node<E> target = getNode(index);Node<E> prev = target.pre;Node<E> newNode = new Node<>(prev, element, target);if (prev == null) {head = newNode;} else {prev.next = newNode;}target.pre = newNode;size++;}/*** 移除并返回列表中指定位置的元素** @param index 要移除元素的索引* @return 被移除的元素* @throws IndexOutOfBoundsException 如果索引超出范圍*/@Overridepublic E remove(int index) {rangeCheck(index);return unlink(getNode(index));}/*** 從列表中移除首次出現的指定元素** @param element 要移除的元素* @return 如果列表包含該元素則返回true*/@Overridepublic boolean remove(E element) {for (Node<E> x = head; x != null; x = x.next) {if (Objects.equals(element, x.value)) {unlink(x);return true;}}return false;}/*** 替換列表中指定位置的元素** @param index 要替換元素的索引* @param element 要存儲的元素* @return 先前在指定位置的元素* @throws IndexOutOfBoundsException 如果索引超出范圍*/@Overridepublic E set(int index, E element) {rangeCheck(index);Node<E> node = getNode(index);E oldVal = node.value;node.value = element;return oldVal;}/*** 返回列表中指定位置的元素** @param index 要返回元素的索引* @return 列表中指定位置的元素* @throws IndexOutOfBoundsException 如果索引超出范圍*/@Overridepublic E get(int index) {rangeCheck(index);return getNode(index).value;}/*** 返回列表中的元素數量** @return 列表中的元素數量*/@Overridepublic int size() {return size;}/*** 返回此列表中元素的迭代器** @return 按適當順序包含此列表中所有元素的迭代器*/@Overridepublic Iterator<E> iterator() {return new LinkedListIterator();}// ========== 私有輔助方法 ==========/*** 獲取指定索引處的節點*/private Node<E> getNode(int index) {if (index < (size >> 1)) {Node<E> x = head;for (int i = 0; i < index; i++)x = x.next;return x;} else {Node<E> x = tail;for (int i = size - 1; i > index; i--)x = x.pre;return x;}}/*** 從鏈表中移除指定節點*/private E unlink(Node<E> node) {final E element = node.value;final Node<E> next = node.next;final Node<E> prev = node.pre;if (prev == null) {head = next;} else {prev.next = next;node.pre = null;}if (next == null) {tail = prev;} else {next.pre = prev;node.next = null;}node.value = null;size--;return element;}/*** 檢查索引是否在有效范圍內*/private void rangeCheck(int index) {if (index < 0 || index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 檢查添加操作的索引是否在有效范圍內*/private void rangeCheckForAdd(int index) {if (index < 0 || index > size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 構造索引越界異常信息*/private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+size;}// ========== 內部類實現 ==========/*** 雙向鏈表節點實現*/private static class Node<E> {/*** 前驅節點*/Node<E> pre;/*** 后繼節點*/Node<E> next;/*** 節點存儲的值*/E value;Node(Node<E> pre, E value, Node<E> next) {this.pre = pre;this.value = value;this.next = next;}}/*** 鏈表迭代器實現*/private class LinkedListIterator implements Iterator<E> {/*** 當前迭代節點*/private Node<E> current = head;/*** 檢查是否還有更多元素可迭代** @return 如果迭代有更多元素則返回true*/@Overridepublic boolean hasNext() {return current != null;}/*** 返回迭代中的下一個元素** @return 迭代中的下一個元素* @throws NoSuchElementException 如果迭代沒有更多元素*/@Overridepublic E next() {if (!hasNext())throw new NoSuchElementException();E element = current.value;current = current.next;return element;}}
}

性能考慮

雙向鏈表與數組列表的性能對比:

操作ArrayListLinkedList
隨機訪問O(1)O(n)
頭部插入/刪除O(n)O(1)
尾部插入/刪除平均O(1)O(1)
中間插入/刪除O(n)O(n)
內存占用更緊湊每個元素額外占用空間

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/85148.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/85148.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/85148.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【深度學習】卷積神經網絡(CNN):計算機視覺的革命性引擎

卷積神經網絡&#xff08;CNN&#xff09;&#xff1a;計算機視覺的革命性引擎 一、算法背景&#xff1a;視覺智能的進化之路1.1 傳統視覺處理的困境1.2 神經科學的啟示 二、算法理論&#xff1a;CNN的核心架構2.1 基礎組成單元卷積層&#xff1a;特征提取引擎池化層&#xff1…

使用@SpringJUnitConfig注解開發遇到的空指針問題

Spring測試中的版本陷阱&#xff1a;SpringJUnitConfig與JUnit版本兼容性深度解析 一個看似簡單的空指針異常&#xff0c;背后可能隱藏著JUnit版本不匹配的“幽靈”。 一、SpringJUnitConfig&#xff1a;Spring與JUnit 5的橋梁 SpringJUnitConfig是Spring TestContext框架為**…

[2025CVPR]AdcSR:一種高效實世界圖像超分辨率的對抗擴散壓縮方法

目錄 1. 背景與挑戰 2. AdcSR模型概述 2.1 模型架構 2.2 訓練策略 3. 公式與原理 4. 創新點 5. 實驗與結果 5.1 實驗設置 5.2 結果對比 5.3 消融實驗 6. 結論 在計算機視覺領域&#xff0c;圖像超分辨率&#xff08;Image Super-Resolution, ISR&#xff09;一直是一…

Go 語言中的字符串基本操作

這篇文章已經放到騰訊智能工作臺的知識庫啦&#xff0c;鏈接在這里&#xff1a;ima.copilot-Go 入門到入土。要是你有啥不懂的地方&#xff0c;就去知識庫找 AI 聊一聊吧。 本篇將詳細講解 Go 語言中與字符串相關的操作。 1、rune 和 字符串長度 1、Go 函數語法約定 在開始…

數學建模會議筆記

看似優化模型 建立整數規劃模型 用優化軟件、啟發式方法、精確方法求解 建立圖論和組合優化模型用組合優化方法、啟發式方法求解 建立博弈論模型 數據統計分析與可視化- 數據擬合、參數估計、插值、數據的標準化、去偽補全相關度分析、分類、聚類等 最優化理論和方法 線性規劃…

學習昇騰開發的六天--ACL應用開發之運行第一個實例

1、下載一個實例&#xff0c;運行一個圖像分類實例&#xff08;環境&#xff1a;Ubuntu22.04&#xff0c;硬件&#xff1a;昇騰310B1&#xff0c;加速模塊&#xff1a;atlas 200i a2&#xff09; samples: CANN Samples - Gitee.com 目錄結構如下&#xff1a; ├── data │…

可靈AI-快手公司自主研發的一款AI視頻與圖像生成工具

可靈AI是由快手公司自主研發的一款AI視頻與圖像生成工具&#xff0c;于2024年6月正式推出。以下是對其的詳細介紹&#xff1a; 核心功能 AI視頻生成&#xff1a; 文生視頻&#xff1a;輸入文字描述&#xff0c;AI可自動生成匹配的視頻片段。圖生視頻&#xff1a;上傳圖片&…

創客匠人解析:存量時代創始人 IP 打造與免費流量池策略

在存量競爭的商業環境中&#xff0c;企業如何突破增長瓶頸&#xff1f;創客匠人結合新潮傳媒創始人張繼學的實戰洞察&#xff0c;揭示 “品牌 IP” 雙輪驅動下的免費流量池構建邏輯&#xff0c;為知識變現與創始人 IP 打造提供新思路。 一、存量時代的流量革命&#xff1a;從…

提升語義搜索效率:LangChain 與 Milvus 的混合搜索實戰

我從不幻想人生能夠毫無波折&#xff0c;但我期望遭遇困境之際&#xff0c;自身能夠成為它的克星。 概述 LangChain與Milvus的結合構建了一套高效的語義搜索系統。LangChain負責處理多模態數據&#xff08;如文本、PDF等&#xff09;的嵌入生成與任務編排&#xff0c;Milvus作…

MySQL配置簡單優化與讀寫測試

測試方法 先使用sysbench對默認配置的MySQL單節點進行壓測&#xff0c;單表數據量為100萬&#xff0c;數據庫總數據量為2000萬&#xff0c;每次壓測300秒。 sysbench --db-drivermysql --time300 --threads10 --report-interval1 \--mysql-host192.168.0.10 --mysql-port3306…

獵板深耕透明 PCB,解鎖電子設計新邊界

在電子技術快速迭代的當下&#xff0c;獵板始終關注行業前沿&#xff0c;透明 PCB 作為極具創新性的技術&#xff0c;正在改變電子設備的設計與應用格局。? 從傳統的綠色、棕色 PCB 到如今的透明 PCB&#xff0c;其突破在于特殊基材與導電材料的運用&#xff0c;實現 85%-92%…

FLAML:快速輕量級自動機器學習框架

概述 FLAML&#xff08;Fast and Lightweight AutoML&#xff09;是微軟開發的一個高效的自動機器學習&#xff08;AutoML&#xff09;框架。它專注于在有限的計算資源和時間約束下&#xff0c;自動化機器學習管道的構建過程&#xff0c;包括特征工程、模型選擇、超參數調優等…

Github 以及 Docker的 wsl --list --online無法訪問問題

修改電腦DNS 騰訊 DNS IP&#xff1a;119.29.29.29 備用&#xff1a;182.254.116.116 阿里DNS IP&#xff1a;223.5.5.5 223.6.6.6 百度DNS IP:180.76.76.76 谷歌DNS IP:8.8.8.8

Go 語言中的變量和常量

這篇文章已經放到騰訊智能工作臺的知識庫啦&#xff0c;鏈接在這里&#xff1a;ima.copilot-Go 入門到入土。要是你有啥不懂的地方&#xff0c;就去知識庫找 AI 聊一聊吧。 1、變量的聲明與使用 我們來探討編程語言中最核心的概念之一&#xff1a;變量。 1、靜態語言中的變量…

破局傳統訂貨!云徙渠道訂貨系統賦能企業數字化渠道升級

在數字化浪潮的推動下&#xff0c;傳統經銷商訂貨模式面臨著諸多挑戰&#xff0c;如信息孤島、系統崩潰、移動化不足等問題。云徙渠道訂貨系統憑借其創新的數字化架構和強大的功能模塊&#xff0c;正在成為企業實現渠道數字化轉型的重要工具。 系統功能與創新 云徙渠道訂貨系統…

SQL關鍵字三分鐘入門:UNION 與 UNION ALL —— 數據合并全攻略

在處理數據時&#xff0c;有時我們需要將來自不同表或同一表的不同查詢結果合并在一起。例如&#xff1a; 合并兩個部門的員工名單&#xff1b;將多個地區的銷售數據匯總&#xff1b;顯示某段時間內所有新增和修改的記錄。 這時候&#xff0c;我們就需要用到 SQL 中非常強大的…

SNMPv3 的安全命名空間詳解

1. 安全命名空間的本質 安全命名空間是 SNMPv3 的核心安全機制&#xff0c;通過 上下文&#xff08;Context&#xff09; 實現&#xff1a; #mermaid-svg-6cV9146nTFF1zCMJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#merma…

【嵌入式硬件實例】-555定時器實現煙霧和易燃氣體泄露檢測

555定時器實現煙霧和易燃氣體泄露檢測 文章目錄 555定時器實現煙霧和易燃氣體泄露檢測1、555定時器介紹2、MQ-2 氣體/煙霧傳感器模塊介紹3、硬件準備與接線在本文中,我們將使用555定時器和MQ-2氣體傳感器構建一個氣體泄漏檢測和報警系統。它在煤氣泄漏期間用作家庭安全警報器。…

【機器人】DualMap 具身導航 | 動態場景 開放詞匯語義建圖 導航系統

DualMap 是一個在線的開放詞匯語義映射系統&#xff0c;使得機器人能夠通過自然語言查詢在動態變化的環境中理解和導航 雙地圖導航&#xff0c;結合全局抽象地圖進行高層次候選選擇&#xff0c;以及局部具體地圖進行精確目標定位&#xff0c;有效管理和更新環境中的動態變化。…

【Fifty Project - D37】

fifty project算是失敗了一半了 成功的那一半在于一定程度上拯救了我的作息和健康&#xff0c;兩個月前入職體檢的肝有點不健康&#xff0c;昨天復查發現全都回到了健康范圍&#xff01;尿酸也在正常范圍&#xff01;就是體重還是沒減下來hhh 失敗的一半在于自己很差勁的規劃能…