鏈表原理與實現:從單鏈表到LinkedList

1.鏈表的概念及結構

鏈表是一種物理存儲結構上非連續存儲結構,數據元素的邏輯順序是通過鏈表中的引用鏈接次序實現的 。 可以形象的理解,在邏輯上來看,鏈表就像是一節節火車車廂。

鏈表的分類:鏈表的結構有很多種,單向或雙向、帶頭或不帶頭、循環或不循環。這篇文章就從最簡單的鏈表結構講起———不帶頭單向非循環鏈表(單鏈表)。

2.單鏈表模擬實現

為了更好的學習對于單鏈表的操作。我們自己模擬實現一些基本的功能。

1.準備工作

接口

package List;public interface IList {//頭插法void addFirst(int data);//尾插法public void addLast(int data);//任意位置插入,第一個數據節點為0號下標public void addIndex(int index,int data);//查找是否包含關鍵字key是否在單鏈表當中public boolean contains(int key);//刪除第一次出現關鍵字為key的節點public void remove(int key);//刪除所有值為key的節點public void removeAllKey(int key);//得到單鏈表的長度public int size();//清空public void clear() ;//打印public void display() ;
}

通過實現接口中的抽象方法實現單鏈表增刪查改的實現。

單鏈表的定義

單鏈表(SinglyLinkedList)的定義需要定義單個節點ListNode。單個節點有data存儲數據,next存儲下一個節點的引用。同時單鏈表還需要一個成員變量head存儲單鏈表的頭位置。基于以上的需要可以把ListNode定義為單鏈表的內部類。

public class SinglyLinkedList {public class ListNode{public int data;public ListNode next;public ListNode(int data) {this.data = data;}}public ListNode head;
}

2.具體接口實現

添加

頭插
@Overridepublic void addFirst(int data) {ListNode newnode = new ListNode(data);newnode.next = head;head = newnode;}
尾插
@Overridepublic void addLast(int data) {ListNode newnode = new ListNode(data);//鏈表為空if(head == null){head = newnode;return;}//鏈表不為空,找尾尾插ListNode cur = head;while (cur.next != null){cur = cur.next;}cur.next = newnode;}
在index位置插入
private void CheckIndex(int index){int len = this.size();if(index < 0 || index > len){throw new IllegalIndexException("index不合法");}}@Overridepublic void addIndex(int index, int data) {try {CheckIndex(index);ListNode newnode = new ListNode(data);if(index == 0){addFirst(data);}if(index == size()){addLast(data);}ListNode cur = head;while(index - 1 != 0){cur = cur.next;index--;}newnode.next = cur.next;cur.next = newnode;}catch (IllegalIndexException e){e.printStackTrace();}}

?刪除

刪除找到第一個key值
@Overridepublic void remove(int key) {if(head == null){return;}//解決頭節點問題if(head.data == key){head = head.next;return;}ListNode cur = head;while(cur.next.data != key){cur = cur.next;}ListNode del = cur.next;cur.next = del.next;}
刪除所有等于key的值
@Overridepublic void removeAllKey(int key) {if(head == null){return;}ListNode prev = head;ListNode cur = head.next;while (cur != null){if(cur.data == key){prev.next = cur.next;}else {prev = cur;}cur = cur.next;}//解決頭節點data等于key的情況if(head.data == key){head = head.next;}}

查找

@Overridepublic boolean contains(int key) {ListNode cur = head;while (cur != null){if(cur.data == key){return true;}cur = cur.next;}return false;}

得到size

@Overridepublic int size() {int count = 0;ListNode cur = head;while(cur != null){count++;cur = cur.next;}return count ;}

清空

@Overridepublic void clear() {ListNode cur = head;while(cur != null){ListNode ret = cur;cur.next = null;cur = ret.next;}head = null;}

打印

@Overridepublic void display() {ListNode cur = this.head;while(cur != null){System.out.print(cur.data + " ");cur = cur.next;}System.out.println();}

2.鏈表oj

看這篇文章:單鏈表oj練習(C語言版)

雖然是C語言完成的,但是做題的思想是一樣的。

3.LinkedList的模擬實現

LinkedList是java標準庫提供的雙向鏈表的實現。還是一樣為了更好的理解并運用,先自己模擬實現一個。

1.準備工作

接口

接口和上面的單鏈表接口一樣。

MyLinkedList的定義

和上面的單鏈表不同的是ListNode里多一個prev用于存儲上一個節點的引用MyLinkedList多一個成員last存儲雙向鏈表的尾

2.具體接口實現

添加

@Overridepublic void addFirst(int data) {ListNode newnode = new ListNode(data);if(head == null){head = last = newnode;}else {newnode.next = head;head.prev = newnode;head = newnode;}}@Overridepublic void addLast(int data) {ListNode newnode = new ListNode(data);if(head == null){head = last = newnode;}else {last.next = newnode;newnode.prev = last;last = newnode;}}private void CheckIndex(int index){if(index < 0 || index > size()){throw new IllegalIndexException("index位置不合法");}}private ListNode FindIndexnode(int index){ListNode cur = head;while(index-1 > 0){cur = cur.next;index--;}return cur;}@Overridepublic void addIndex(int index, int data) {try {CheckIndex(index);if(index == 0){addFirst(data);}if(index == size()){addLast(data);}ListNode newnode = new ListNode(data);ListNode cur = FindIndexnode(index);newnode.next = cur;cur.prev.next = newnode;newnode.prev = cur.prev;newnode.next = cur;}catch(IllegalIndexException e){e.printStackTrace();}}

刪除

@Overridepublic void remove(int key) {ListNode cur = head;while(cur != null){if(cur.data == key){if(cur == head){head = head.next;if(head != null){head.prev = null;}}else {cur.prev.next = cur.next;if (cur.next == null) {last = last.prev;} else {cur.next.prev = cur.prev;}}return;}cur = cur.next;}}@Overridepublic void removeAllKey(int key) {ListNode cur = head;while(cur != null){if(cur.data == key){if(cur == head){head = head.next;if(head != null){head.prev = null;}}else {cur.prev.next = cur.next;if (cur.next == null) {last = last.prev;} else {cur.next.prev = cur.prev;}}}cur = cur.next;}}

查找 打印 得到size

和單鏈表一樣,本質都是遍歷鏈表

清空

@Overridepublic void clear() {ListNode cur = head;while(cur != null){ListNode Curn = cur.next;cur.prev = null;cur.next = null;cur = Curn;}head = last = head;}

4.LinkedList的使用?

1.構造

public static void main(String[] args) {// 構造一個空的LinkedListList<Integer> list1 = new LinkedList<>();List<String> list2 = new java.util.ArrayList<>();list2.add("JavaSE");list2.add("JavaWeb");list2.add("JavaEE");// 使用ArrayList構造LinkedListList<String> list3 = new LinkedList<>(list2);
}

2.其他方法?

?

?

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

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

相關文章

替換word中的excel

PostMapping("/make/report/target/performance/first") public AjaxResult makeTargetReportFirst(RequestBody MakeReportDTO makeReportDTO) {Map<String, String> textReplaceMap new HashMap<>();// 替換日期LocalDateTime nowData LocalDateTime…

深入探索百度智能云千帆AppBuilder:從零開始構建AI應用

在數字化轉型的浪潮中&#xff0c;企業對高效、智能的應用開發平臺的需求日益增長。百度智能云千帆AppBuilder&#xff08;以下簡稱AppBuilder&#xff09;憑借其強大的功能和靈活的開發方式&#xff0c;成為企業級大模型應用開發的理想選擇。本文將詳細介紹如何使用AppBuilder…

測試工程師要如何開展單元測試

單元測試是軟件開發過程中至關重要的環節&#xff0c;它通過驗證代碼的最小可測試單元(如函數、方法或類)是否按預期工作&#xff0c;幫助開發團隊在早期發現和修復缺陷&#xff0c;提升代碼質量和可維護性。以下是測試工程師開展單元測試的詳細步驟和方法&#xff1a; 一、理…

NODE-I916 I721模塊化電腦發布,AI算力與超低功耗的完美平衡

在智能工業與邊緣計算蓬勃發展的今天&#xff0c;企業對計算設備的性能與能效需求日益嚴苛。全新推出NODE-I916與NODE-I721模塊化電腦&#xff0c;分別搭載英特爾 酷睿? Ultra 平臺與Alder Lake-N平臺&#xff0c;以差異化CPU配置為核心&#xff0c;為AI推理、工業自動化及嵌入…

采集需要登錄網站的教程

有些網站需要用戶登錄才能顯示相關信息&#xff0c;如果要采集這類網站&#xff0c;有以下幾個方法&#xff1a; 1. 寫發布模塊來抓包獲取post的數據&#xff1b; 2. 有些采集器內置瀏覽器獲取這些信息&#xff0c;但是經常獲取的不準確&#xff0c;可靠性太低&#xff1b; 3. …

六足連桿爬行機器人的simulink建模與仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序 4.系統原理簡介 5.完整工程文件 1.課題概述 六足連桿爬行機器人的simulink建模與仿真。通過simulink&#xff0c;對六足機器人的六足以及機身進行simulink建模&#xff0c;模擬其行走&#xff0c;仿真輸出機器人行走時六足的坐…

什么是物聯網 (IoT):2024 年物聯網概述

物聯網&#xff08;IoT&#xff09;是一個有望徹底改變我們生活、工作以及與環境互動方式的概念。如今&#xff0c;越來越多的新興企業和老牌企業都在利用物聯網的力量創造創新產品與服務。正因為這一轉變&#xff0c;互聯互通已成為我們生活中不可或缺的一部分&#xff0c;科技…

MVC入門(5)-- HttpMessageConverter 消息轉換器

概念 HttpMessageConverter 是 Spring 框架中用于處理 HTTP 請求和響應數據的核心接口&#xff0c;負責在 Java 對象與 HTTP 消息體&#xff08;請求體或響應體&#xff09;之間進行雙向轉換。簡單來說&#xff0c;它是 Spring 用來將 HTTP 請求中的原始數據&#xff08;如 JS…

Spark,連接MySQL數據庫,添加數據,讀取數據

以下是使用Spark連接MySQL數據庫、添加數據和讀取數據的步驟&#xff08;基于Scala API&#xff09;&#xff1a; 1. 準備工作 - 添加MySQL驅動依賴 在Spark項目中引入MySQL Connector JAR包&#xff08;如 mysql-connector-java-8.0.33.jar &#xff09;&#xff0c;或通過Sp…

關于 APK 反編譯與重構工具集

一、apktool — APK 解包 / 重打包 apktool 是一款開源的 Android APK 工具&#xff0c;用于&#xff1a; 反編譯 APK 查看資源和布局文件 生成 smali 文件&#xff08;DEX 的反匯編&#xff09; 對 APK 進行修改后重新打包 它不能還原 Java 源碼&#xff0c;只能將 D…

[解決方案] Word轉PDF

背景&#xff1a; 之前做過一些pdf導出&#xff0c; 客戶提了一個特別急的需求&#xff0c; 要求根據一個模版跟一個csv的數據源&#xff0c; 批量生成PDF&#xff0c; 因為之前用過FOP&#xff0c; 知道調整樣式需要特別長的時間&#xff0c; 這個需求又特別急&#xff0c; 所…

01 基本介紹及Pod基礎

01 查看各種資源 01-1 查看K8s集群的內置資源 [rootmaster01 ~]# kubectl api-resources NAME SHORTNAMES APIVERSION NAMESPACED KIND bindings v1 …

19 C 語言位運算、賦值、條件、逗號運算符詳解:涵蓋運算符優先級與復雜表達式計算過程分析

1 位運算符 位運算符是對整數的二進制表示&#xff08;補碼形式&#xff09;進行逐位操作的運算符。以下是主要的位運算符及其功能描述&#xff1a; 運算符描述操作數個數副作用&按位與2無|按位或2無^按位異或2無~按位取反1無<<按位左移2無>>按位右移2無 1.1…

哈希查找方法

已知哈希表長度為11&#xff0c;哈希函數為H&#xff08;key&#xff09;&#xff1d;key&#xff05;11&#xff0c;隨機產生待散列的小于50的8個元素&#xff0c;同時采用線性探測再散列的方法處理沖突。任意輸入要查找的數據&#xff0c;無論是否找到均給出提示信息。 int f…

JavaScript性能優化實戰(10):前端框架性能優化深度解析

引言 React、Vue、Angular等框架雖然提供了強大的抽象和開發效率,但不恰當的使用方式會導致嚴重的性能問題,針對這些問題,本文將深入探討前端框架性能優化的核心技術和最佳實踐。 React性能優化核心技術 React通過虛擬DOM和高效的渲染機制提供了出色的性能,但當應用規模…

類和對象------2

目錄 一. C面向對象模型初探1 .成員變量和函數的存儲 二 this指針1 &#xff09;this指針工作原理2 &#xff09;this指針的使用3&#xff09; const修飾成員函數4 &#xff09;const修飾對象(常對象) 3.友元1 )友元語法2) 課堂練習 4 強化訓練(數組類封裝) 四 運算符重載&…

量子計算在金融科技中的應用前景

隨著量子計算技術的飛速發展&#xff0c;其在各行業的應用潛力逐漸顯現&#xff0c;金融科技領域更是備受關注。量子計算的強大計算能力有望為金融行業帶來前所未有的變革&#xff0c;從風險評估到投資組合優化&#xff0c;從高頻交易到加密技術&#xff0c;量子計算都可能成為…

Redisson 四大核心機制實現原理詳解

一、可重入鎖&#xff08;Reentrant Lock&#xff09; 可重入鎖是什么&#xff1f; 通俗定義 可重入鎖類似于一把“智能鎖”&#xff0c;它能識別當前的鎖持有者是否是當前線程&#xff1a; 如果是&#xff0c;則允許線程重復獲取鎖&#xff08;重入&#xff09;&#xff0c;并…

srs-7.0 支持obs推webrtc流

demo演示 官方教程: https://ossrs.net/lts/zh-cn/blog/Experience-Ultra-Low-Latency-Live-Streaming-with-OBS-WHIP 實現原理就是通過WHIP協議來傳輸 SDP信息 1、運行 ./objs/srs -c conf/rtc.conf 2、obs推流 3、web端播放webrtc流 打開web:ht

面試題——JDBC|Maven|Spring的IOC思想|DI思想|SpringMVC

目錄 一、JDBC 1、jdbc連接數據庫的基本步驟&#xff08;掌握**&#xff09; 2、Statement和PreparedStatement的區別 &#xff08;掌握***&#xff09; 二、Maven 1、maven的作用 2、maven 如何排除依賴 3、maven scope作用域有哪些&#xff1f; 三、Spring的IOC思想 …