單鏈表的手動實現+相關OJ題

目錄

鏈表的介紹

單鏈表的手動實現

單鏈表的基本框架

打印鏈表:

獲取表長:

頭插法新增節點:

尾插法新增節點:

在指定下標插入:

鏈表的查找

?刪除鏈表中第一個出現的key:

刪除鏈表中所有key值

鏈表置空

?總代碼

測試代碼

?鏈表相關的OJ題

1.反轉單鏈表

?思路:?

2.查找鏈表中間節點

?思路:1.判空;2.定義兩個指針,都指向head;3.設置循環,每次循環一個指針走兩步一個指針走一步,當走的快的那個指針到達最后一個節點時,慢的節點就在中間;


鏈表的介紹

基于順序表具有,插入數據,空間不足時要擴容,擴容有性能消耗和插入刪除數據時有時候需要大量的挪動數據,導致程序的執行效率低的缺點,延升出了鏈表。

鏈表,是一種邏輯結構連續物理結構不一定連續的一種數據結構;由一個個的節點組成,每個節點包含數據域和指針域,指針域指向下一個節點。

單鏈表的手動實現

單鏈表的基本框架

//不帶頭結點的單鏈表
public class MySingleList implements IList{//鏈表由若干個頭結點組成,每個節點都是一個完整的部分,所以可以定義一個內部類static class ListNode{public int val;//數據域public ListNode next;//指針域 存放下一個節點的地址public ListNode(int val) {this.val = val;}}public ListNode head;//定義一個存放節點的變量,默認值為null@Overridepublic void addFirst(int data) {}@Overridepublic void addLast(int data) {}@Overridepublic void addIndex(int index, int data) {}@Overridepublic boolean contains(int key) {return false;}@Overridepublic void remove(int key) {}@Overridepublic void removeAllKey(int key) {}@Overridepublic int size() {return 0;}@Overridepublic void clear() {}@Overridepublic void display() {}
}

為了更好的理解這個單鏈表的操作,我們先創建單鏈表的方法:

    public ListNode head;//定義一個存放節點的變量,默認值為nullpublic void createList(){//1.通過實例化ListNode創建幾個節點ListNode node1 = new ListNode(12);ListNode node2 = new ListNode(22);ListNode node3 = new ListNode(32);ListNode node4 = new ListNode(42);//2.根據單鏈表的形態,把節點鏈接起來node1.next = node2;node2.next = node3;node3.next = node4;this.head = node1;}

打印鏈表:

    public void display() {//1.借助一個cur節點去遍歷鏈表,移動cur的位置ListNode cur = head;while (cur !=null){//cur=null表示整個鏈表都走完了System.out.print(cur.val+" ");cur = cur.next;}System.out.println();}

注意區分循環條件?cur !=null 和cur.next?!=null

獲取表長:

獲取表長的方法是打印方法衍生出來的,無非就是打印的方法中加一個計數器去記表長:

    public int size() {ListNode cur = head;int count = 0;while (cur != null){//注意這個循環條件count++;cur = cur.next;}return count;}

頭插法新增節點:

    public void addFirst(int data) {//1.實例化一個節點ListNode node = new ListNode(data);//2.新增節點的指針域指向頭節點更新頭結點 順序不可變node.next = head;this.head = node;}

?注意:

  • 插入數據時先綁定后面,如果我們先綁定前面的話會發生什么呢?當this.head = node先執行的完后,新增節點指針域該指向誰了,為了防止數據丟失,插入數據時因先綁定后面

尾插法新增節點:

    public void addLast(int data) {ListNode node = new ListNode(data);//1.找到鏈表最后一個節點if (head == null){head = node;}else {//遍歷鏈表去找ListNode cur = head;while (cur.next != null) {cur = cur.next;}cur.next = node ;//增}}

在指定下標插入:

    public void addIndex(int index, int data) {//1.判斷index的合法性if (index < 0 || index > size()){throw new IndexException("index非法"+index);}//表空的情況ListNode node = new ListNode(data);if (head == null){head = node;return;}//2.在0位置插入時調用頭插if (index == 0 ){addFirst(data);return;}//3.index=size()尾插法if (index == size()){addLast(data);return;}//在index位置插入時,找到index位置的前一個節點去操作ListNode cur = findPrevIndex(index);node.next = cur.next;cur.next = node;}private ListNode findPrevIndex(int index){ListNode cur = head;int count = 0;while (count != index - 1){count++;cur = cur.next;}return cur;}

鏈表的查找

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

?刪除鏈表中第一個出現的key:

   public void remove(int key) {//1.表空if (head == null){return;}//2.頭結點刪除if (head.val == key){head = head.next;return;}//3.中間元素刪除找key的前驅節點去操作ListNode cur = findPrevKey(key);cur.next = cur.next.next;//也可以借助一個變量去刪除/*ListNode del = cur.next;cur.next = del.next;*/}//盡量以方法的方式去實現功能,降低代碼的耦合度private ListNode findPrevKey(int key){ListNode cur = head;while (cur.next !=null){if (cur.next.val == key){return cur;}else {cur = cur.next;}}return null;}

刪除鏈表中所有key值

    public void removeAllKey(int key) {if (head == null) {return;}//定義兩個指針分別指向頭和頭的下一個ListNode prev = head;ListNode cur = head.next;//可能要被移除的元素while (cur != null) {//遍歷if (cur.val == key) {prev.next = cur.next;cur = cur.next;} else {//不用刪除就往后繼續遍歷prev = cur;cur = cur.next;}//此時除了頭結點其他節點都遍歷完了,就判斷頭節點if (head.val == key) {head = head.next;}}}

鏈表置空

    public void clear() {//法1:循環把每個節點都置空//法2:直接把最開始的節點中(只要是沒有人引用的對象內存都會回收置空),這樣就把整個鏈表置空了head = null;}

?總代碼

//不帶頭結點的單鏈表
public class MySingleList implements IList{//鏈表由若干個頭結點組成,每個節點都是一個完整的部分,所以可以定義一個內部類static class ListNode{public int val;//數據域public ListNode next;//指針域 存放下一個節點的地址public ListNode(int val) {this.val = val;}}public ListNode head;//定義一個存放節點的變量,默認值為nullpublic void createList(){//1.通過實例化ListNode創建幾個節點ListNode node1 = new ListNode(12);ListNode node2 = new ListNode(22);ListNode node3 = new ListNode(32);ListNode node4 = new ListNode(42);//2.根據單鏈表的形態,把節點鏈接起來node1.next = node2;node2.next = node3;node3.next = node4;this.head = node1;}@Overridepublic void addFirst(int data) {//1.實例化一個節點ListNode node = new ListNode(data);//2.新增節點的指針域指向頭節點更新頭結點node.next = head;this.head = node;}@Overridepublic void addLast(int data) {ListNode node = new ListNode(data);//1.找到鏈表最后一個節點if (head == null){head = node;}else {//遍歷鏈表去找ListNode cur = head;while (cur.next != null) {cur = cur.next;}cur.next = node ;//增}}@Overridepublic void addIndex(int index, int data) {//1.判斷index的合法性if (index < 0 || index > size()){throw new IndexException("index非法"+index);}//表空的情況ListNode node = new ListNode(data);if (head == null){head = node;return;}//2.在0位置插入時調用頭插if (index == 0 ){addFirst(data);return;}//3.index=size()尾插法if (index == size()){addLast(data);return;}//在index位置插入時,找到index位置的前一個節點去操作ListNode cur = findPrevIndex(index);node.next = cur.next;cur.next = node;}private ListNode findPrevIndex(int index){ListNode cur = head;int count = 0;while (count != index - 1){count++;cur = cur.next;}return cur;}@Overridepublic boolean contains(int key) {ListNode cur = head;while (cur !=null){if (cur.val == key){return true;}cur = cur.next;}return false;}@Overridepublic void remove(int key) {//1.表空if (head == null){return;}//2.頭結點刪除if (head.val == key){head = head.next;return;}//3.中間元素刪除找key的前驅節點去操作ListNode cur = findPrevKey(key);cur.next = cur.next.next;//也可以借助一個變量去刪除/*ListNode del = cur.next;cur.next = del.next;*/}//盡量以方法的方式去實現功能,降低代碼的耦合度private ListNode findPrevKey(int key){ListNode cur = head;while (cur.next !=null){if (cur.next.val == key){return cur;}else {cur = cur.next;}}return null;}@Overridepublic void removeAllKey(int key) {if (head == null) {return;}//定義兩個指針分別指向頭和頭的下一個ListNode prev = head;ListNode cur = head.next;//可能要被移除的元素while (cur != null) {//遍歷if (cur.val == key) {prev.next = cur.next;cur = cur.next;} else {//不用刪除就往后繼續遍歷prev = cur;cur = cur.next;}//此時除了頭結點其他節點都遍歷完了,就判斷頭節點if (head.val == key) {head = head.next;}}}@Overridepublic int size() {ListNode cur = head;int count = 0;while (cur != null){count++;cur = cur.next;}return count;}@Overridepublic void clear() {//法1:循環把每個節點都置空//法2:直接把最開始的節點中(只要是沒有人引用的對象內存都會回收置空),這樣就把整個鏈表置空了head = null;}@Overridepublic void display() {if (head == null){System.out.println("鏈表為空");return;}//1.借助一個cur節點去遍歷鏈表,移動cur的位置ListNode cur = head;while (cur !=null){//cur=null表示整個鏈表都走完了System.out.print(cur.val+" ");cur = cur.next;}System.out.println();}}

測試代碼

public class Test {public static void main(String[] args) {MySingleList mySingleList = new MySingleList();mySingleList.createList();System.out.println();mySingleList.display();//12 22 32 42System.out.println(mySingleList.size());//4mySingleList.addFirst(2);mySingleList.display();//2 12 22 32 42mySingleList.addLast(52);mySingleList.display();//2 12 22 32 42 52mySingleList.addIndex(2,20);mySingleList.display();//2 12 20 22 32 42 52System.out.println(mySingleList.contains(52));//truemySingleList.remove(12);mySingleList.display();//2 20 22 32 42 52mySingleList.addLast(2);mySingleList.addIndex(3,2);mySingleList.display();//2 20 22 2 32 42 52 2mySingleList.removeAllKey(2);mySingleList.display();//20 22 32 42 52mySingleList.clear();mySingleList.display();//鏈表為空}
}

?鏈表相關的OJ題

1.反轉單鏈表

反轉一個單鏈表

?思路:

    public ListNode reverseList(){if (head == null){return null;}if (head.next == null){return head;}//ListNode cur = head.next;//定義一個cur記錄當前需要反轉的節點head.next = null;while(cur != null){ListNode curNext = cur.next;//記錄下一個反轉點cur.next = head;//當前要反轉的節點指向headhead = cur;//更新headcur = curNext;//更新cur}return head;}

2.查找鏈表中間節點

題目

?思路:1.判空;2.定義兩個指針,都指向head;3.設置循環,每次循環一個指針走兩步一個指針走一步,當走的快的那個指針到達最后一個節點時,慢的節點就在中間;

    public ListNode middleNode(){if (head == null){return null;}ListNode fast = head;ListNode slow = head;while (fast != null && fast.next !=null){//順序不能反,否則報空指針異常fast = fast.next.next;slow = slow.next;}return slow;}

?感謝大家閱讀📚點贊👍收藏?評論?關注?

博客主頁: 【長毛女士-CSDN博客?

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

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

相關文章

梯度提升之原理

簡介 梯度提升主要是基于數學最值問題 數學描述 目標函數為 obj(θ)∑i1nl(yi,y^i(t))∑k1tw(fk)obj(\theta) \sum_{i1}^n l(y_i, \hat y_i^{(t)}) \sum_{k1}^t w(f_k)obj(θ)i1∑n?l(yi?,y^?i(t)?)k1∑t?w(fk?) 其中ttt表示集成的樹的個數&#xff0c;y^i(t)y^i(t?1)…

[學習] Hilbert變換:從數學原理到物理意義的深度解析與仿真實驗(完整實驗代碼)

Hilbert變換&#xff1a;從數學原理到物理意義的深度解析與仿真實驗 文章目錄Hilbert變換&#xff1a;從數學原理到物理意義的深度解析與仿真實驗一、數學原理二、作用與物理意義1.構造解析信號2.相位移動特性3.應用場景三、仿真實驗實驗1&#xff1a;正弦信號的Hilbert變換實驗…

對話弋途科技:當AI重構汽車大腦,一場車載操作系統的“覺醒年代“開始了

&#xff08;圖片來源&#xff1a;Pixels&#xff09;站在未來看歷史&#xff0c;AI汽車剛剛開始。數科星球原創作者丨苑晶編輯丨大兔當特斯拉的自動駕駛仍在全球引發爭議時&#xff0c;中國智能汽車戰場已悄然開啟第二幕。從"四個輪子的大手機"到"移動智能空間…

?機器學習量化交易模型全面剖析報告基于因子庫的機器學習交易模型構建指南

目錄 第一章&#xff1a;機器學習在加密貨幣量化交易中的應用概述 范式轉變&#xff1a;從傳統因子到機器學習驅動的策略 為什么選擇機器學習&#xff1f;機遇、挑戰與核心概念 機遇 挑戰 核心概念 第二章&#xff1a;為機器學習準備您的因子庫 理解量化因子作為機器學…

內容創作智能體:多模態內容生成的完整解決方案

內容創作智能體&#xff1a;多模態內容生成的完整解決方案 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 總有一行代碼&#xff0c;能點亮萬千星辰。 &#x1f50d; 在技術的宇宙中&#xff0c;我愿做永不停歇的探索者。 ? 用代碼丈量世界&…

測試學習之——Pytest Day4

Pytest作為Python中功能強大且易于使用的測試框架&#xff0c;深受開發者喜愛。它不僅提供了簡潔的測試編寫方式&#xff0c;還通過豐富的配置選項、靈活的標記機制和強大的數據驅動能力&#xff0c;極大地提升了測試效率和可維護性。本文將深入探討Pytest的配置意義與層級、常…

【軟件系統架構】系列七:系統性能——路由器性能深入解析

目錄 一、路由器的核心功能 二、路由器性能核心指標 1. 吞吐量&#xff08;Throughput&#xff09; 2. 并發連接數&#xff08;Session Capacity&#xff09; 3. 每秒連接數&#xff08;CPS&#xff0c;Connections Per Second&#xff09; 4. 轉發延遲&#xff08;Laten…

【數據結構】第一講 —— 概論

【數據結構】第一講 —— 概論 文章目錄【數據結構】第一講 —— 概論1.1 基本概念和常用術語1.2 了解數據結構1. 數據結構2. 數據的邏輯結構3. 數據的物理結構&#xff08;存儲結構&#xff09;4. 數據的運算1.3 算法的描述和分析1.3.1 算法的描述1.3.21.1 基本概念和常用術語…

全面解析MySQL(2)——CRUD基礎

1.CreateCreate(創建)&#xff1a;添加新數據到數據庫中#基礎語法 insert into table_name (column1,column2,column3, ...) values (value1,value2,value3, ...);1.1 單行全列插入value中值的數量和順序必須和column?致describe demo1; -----------------------------------…

某外企筆試總結——純C語言

這里寫自定義目錄標題一、sizeof 計算&#xff08;32位環境&#xff09;二、簡答題三、數據存儲區域與可修改性四、字符串比較輸出及原因五、數組指針運算輸出六、字符串倒序代碼錯誤排查七、下面程序可以把1維數組轉為2維數組&#xff0c;然后調用 printArr2D 打印出數組內容&…

Qt Graphs 模塊擬取代 charts 和 data visualization還有很長的路要走

近期關注 Qt 6.10 的分支進展&#xff0c; 發現了 Qt 6.10 的 charts 和 data visualization &#xff08;以下簡稱 DV&#xff09;已經被deprecated, 功能將會合并到 graphs 模塊。如果后面 charts\ DV 被棄用&#xff0c;那算是很大的API變化了。從Qt 6.5 以后開始引入的 gra…

2025牛客暑期多校訓練營2(部分補題)

題目鏈接&#xff1a;牛客競賽_ACM/NOI/CSP/CCPC/ICPC算法編程高難度練習賽_牛客競賽OJ B Bitwise Perfect 思路 考慮到由&#xff0c;那么只有變小的時候對答案的貢獻才能夠減少&#xff0c;從二進制的角度考慮什么時候變小&#xff0c;只有min(x,y)中的最高位1異或之后變…

Nginx的location匹配規則

Nginx的location匹配規則 為什么你的Nginx配置總是不生效&#xff1f; 改了Nginx配置無數次&#xff0c;reload命令執行了幾十遍&#xff0c;瀏覽器訪問時卻依然返回404&#xff1f;運維工程師小張上周就遇到了這個問題&#xff1a;明明配置了location /static/ { root /var/ww…

USB 2.0 vs USB 3.0:全面技術對比與選擇指南

USB 2.0 vs USB 3.0&#xff1a;全面技術對比與選擇指南 引言 在當今數字時代&#xff0c;USB接口已成為連接設備與計算機的最普遍標準之一。從2000年USB 2.0的發布到2008年USB 3.0的問世&#xff0c;USB技術經歷了顯著的演進。本文將深入比較這兩種廣泛使用的USB標準&#xff…

DApp架構設計與開發流程指南

目錄 DApp架構設計與開發流程指南 引言:DApp的核心特性 一、DApp架構設計 1.1 分層架構設計 各層核心組件: 1.2 典型架構模式 1.2.1 全去中心化架構 1.2.2 混合架構(推薦) 二、開發流程 2.1 敏捷開發流程 2.2 詳細開發階段 階段1:需求分析與設計(1-2周) 階段2:智能合約…

Windows下odbc配置連接SQL Server

一、查看SQL Server服務是否啟動打開SQL Server 2022配置管理器查看SQL Server運行狀態&#xff0c;可以設置 啟動或停止服務二、windows下如何配置ODBC數據源1、Windows搜索欄中輸入“ODBC數據源管理器”并選擇“以管理員身份運行”來打開它2、添加新的數據源ODBC數據源管理器…

MySQL—表設計和聚合函數以及正則表達式

文章目錄一、第一范式&#xff08;原子性&#xff09;二、第二范式&#xff08;消除部分依賴&#xff09;三、第三范式&#xff08;消除傳遞依賴&#xff09;四、表設計五、聚合函數六、正則表達式MySQL 的三大范式&#xff08;1NF、2NF、3NF&#xff09;是關系型數據庫設計的核…

基于Electron打包jar成Windows應用程序

基于Electron打包jar成Windows應用程序簡介注意編譯及命令&#xff1a;運行效果登錄界面用戶管理界面界面全屏鎖屏界面文檔查看界面簡介 本文介紹了一種將maven jar包打包成Windows下EXE可執行程序的方法。 Maven打包Java Web應用成jar&#xff0c;Electron封裝jar成Windows …

Autosar RTE實現觀測量生成-基于ETAS軟件

文章目錄前言觀測量定義arTypedPerInstanceMemoryPorts Measurable工具鏈配置及使用Port中的配置arTypedPerInstanceMemory觀測量生成文件分析總結前言 之前我們在XCP中&#xff0c;對于標定量和觀測量并沒有嚴格按照Autosar標準中定義&#xff0c;Autosar RTE中對標定量和觀測…

【REACT18.x】creat-react-app在添加eslint時報錯Environment key “jest/globals“ is unknown

今天在創建新項目的時候&#xff0c;給cra創建的項目添加eslint支持&#xff0c;出現如下報錯 添加eslint npx eslint --init頁面報錯 Compiled with problems:ERROR [eslint] package.json eslint-config-react-app/jest#overrides[0]:Environment key "jest/globals&…