Java玩轉《啊哈算法》之模擬鏈表

人應該支配習慣,而絕不是讓習慣支配人。一個人要是不能改掉壞習慣,那么他就一文不值。

目錄

  • 代碼地址
  • 模擬鏈表
    • 創建
    • 遍歷打印
    • 插入
    • 插入優化
  • 完整代碼

各位小伙伴們好呀!本人最近看了下《啊哈算法》,寫的確實不錯。

但稍顯遺憾的是,書籍示例代碼是c語言,而不是本人常用的Java。

那就彌補遺憾,說干就干,把這本書的示例語言用java寫一遍, 順帶附上一些自己的理解!

今天這篇博客講的是如何用數組來模擬鏈表。
在這里插入圖片描述

來不及買紙質書但又想盡快感受算法魅力的童鞋也甭擔心,電子版的下載鏈接已經放到下方了,可盡情下載。

鏈接:https://pan.baidu.com/s/1imxiElcCorw2F-HJEnB-PA?pwd=jmgs
提取碼:jmgs

代碼地址

本文代碼已開源:

git clone https://gitee.com/guqueyue/my-blog-demo.git

請切換到gitee分支,

然后查看aHaAlgorithm模塊下的src/main/java/com/guqueyue/aHaAlgorithm/chapter_2_StackAndChainTable即可!

模擬鏈表

在往期的博客中,我們用數組模擬了隊列、棧,并且說了用鏈表也可以模擬隊列、棧。

于是乎,我們還介紹了鏈表,但是鏈表指來指去的難免讓人奇奇怪怪、暈頭轉向。

  1. Java玩轉《啊哈算法》解密QQ號之隊列
  2. Java玩轉《啊哈算法》解密回文之棧
  3. Java玩轉《啊哈算法》之鏈表

那么,這期博客,我們來講一下如何用數組來模擬鏈表。

數組可以模擬隊列、棧,鏈表也可以模擬隊列、棧,數組也能模擬鏈表?沒想到吧。

創建

那么,要怎么用數組來模擬鏈表呢?我們需要準備兩個數組,一個數組存元素,一個數組用來存元素對應的下一個元素的位置
在這里插入圖片描述
如上圖所示,我們data數組用于存放元素內容,right數組用以存放相同索引處對應data數組的下一個元素的索引。

如圖我們頭節點的元素為data[1]也就是2,下一個元素為data[right[1]]也就是3。

當然,我們這里可以做一些小小的改動:

  1. 為了不浪費空間,我們的存放數組的索引從0開始而不是從1開始。
  2. 鏈表尾節點的下一個位置的索引,我們用-1表示,而不是0。

首先,我們聲明一下需要使用的兩個數組、鏈表的長度以便于錄入數據以及控制臺輸入的對象:

   // 用于控制臺輸入private static Scanner scanner = new Scanner(System.in);private static int[] data = new int[101]; // 元素數組private static int[] right = new int[101]; // 索引數組private static int n = 0; // 鏈表長度

然后,我們就可以愉快的編寫創建鏈表的方法了:

   /*** @Description 創建鏈表* @return void**/private static void createChainTable() {System.out.print("請輸入數字個數: ");n = scanner.nextInt();System.out.printf("請輸入%d個數,中間用空格隔開,輸入完回車: ", n);for (int i = 0; i < n; i++) {data[i] = scanner.nextInt();}// 初始化right數組for (int i = 0; i < n; i++) {right[i] = i == n-1 ? -1 : i+1;}}

遍歷打印

有了創建鏈表的方法,當然要有一個打印的方法,不然怎么驗證:

  /*** @Description 打印鏈表* @return void**/private static void printChainTable() {// 輸出int t = 0;System.out.print("鏈表為:" + data[t]);while(right[t] != -1) {t = right[t]; // 獲取下一個元素的索引System.out.print("->" + data[t]);}System.out.println();}

ok了,下面讓我們來驗證一下:

package com.guqueyue.aHaAlgorithm.chapter_2_StackAndChainTable;import java.util.Scanner;/*** @Author: guqueyue* @Description: 用數組模擬鏈表* @Date: 2024/1/15**/
public class ChainTableTest2 {// 用于控制臺輸入private static Scanner scanner = new Scanner(System.in);private static int[] data = new int[101]; // 元素數組private static int[] right = new int[101]; // 索引數組private static int n = 0; // 鏈表長度public static void main(String[] args) {// 創建鏈表createChainTable();// 打印鏈表printChainTable();}/*** @Description 打印鏈表* @return void**/private static void printChainTable() {// 輸出int t = 0;System.out.print("鏈表為:" + data[t]);while(right[t] != -1) {t = right[t]; // 獲取下一個元素的索引System.out.print("->" + data[t]);}System.out.println();}/*** @Description 創建鏈表* @return void**/private static void createChainTable() {System.out.print("請輸入數字個數: ");n = scanner.nextInt();System.out.printf("請輸入%d個數,中間用空格隔開,輸入完回車: ", n);for (int i = 0; i < n; i++) {data[i] = scanner.nextInt();}// 初始化right數組for (int i = 0; i < n; i++) {right[i] = i == n-1 ? -1 : i+1;}}
}

運行代碼,控制臺輸入,可得:
在這里插入圖片描述

插入

在這里插入圖片描述

同樣的,按照書上的邏輯,我們來寫一個往鏈表中插入元素的方法:

   /*** @Description 插入鏈表* @return void**/private static void insertChainTable() {// 插入一個數int len = n;System.out.print("請輸入插入的數:");data[len] = scanner.nextInt();// 按照鏈表順序遍歷 data 數組,找到比 num 大的數int t = 0;while (t != -1) {if (data[right[t]] > data[len]) { // 如果當前節點的下一個節點大于插入數,則插入right[len] = right[t]; // 插入的節點 指向當前節點的下一個節點right[t] = len; // 當前節點 指向插入的節點break;}t = right[t];}}

我們來驗證一下(完整代碼已開源,在本博客最后也可查看):

   public static void main(String[] args) {// 創建鏈表createChainTable();// 打印鏈表printChainTable();// 往鏈表中插入數據insertChainTable();// 打印鏈表printChainTable();}

運行,得:

在這里插入圖片描述
看起來好像沒啥問題,但是同上期博客一樣,存在著兩個問題:

  1. 如果插入的節點值大小小于頭節點,該節點會被插入到頭節點后面,違背了從小到大的順序。
  2. 如果插入的節點值大于等于尾結點,則該節點不會被插入,甚至于直接報錯!

如:
在這里插入圖片描述
又比如:

在這里插入圖片描述

插入優化

因此,我們來把插入方法優化一下,增加插入頭節點和尾節點的邏輯:

	/*** @Description 按照從小到大的順序插入鏈表* @return void**/private static void insertChainTable2() {// 插入一個數int len = n;System.out.print("請輸入插入的數:");data[len] = scanner.nextInt();// 如果新插入的節點比 頭節點 小,則插入到鏈表頭部if (data[len] < data[0]) {// 頭節點和尾節點互換int temp = data[0]; data[0] = data[len]; data[len] = temp;right[len] = right[0]; // 保持舊頭節點原有的連接關系不變right[0] = len; // 將新的頭節點指向舊的節點}else {// 按照鏈表順序遍歷 data 數組,找到比 num 大的數int t = 0;while (right[t] != -1) {if (data[right[t]] > data[len]) { // 如果當前節點的下一個節點大于插入數,則插入right[len] = right[t]; // 插入的節點 指向當前節點的下一個節點right[t] = len; // 當前節點 指向插入的節點break;}t = right[t];}// 插入的數如果比鏈表的最后一個節點大,則插入到鏈表尾部if (right[t] == -1) {right[n-1] = len;right[len] = -1;}}}

改動代碼,來驗證一下吧:

public static void main(String[] args) {// 創建鏈表createChainTable();// 打印鏈表printChainTable();// 往鏈表中插入數據
//        insertChainTable();insertChainTable2();// 打印鏈表printChainTable();
}

運行代碼,分別驗證,插入中間節點:

在這里插入圖片描述
頭節點:
在這里插入圖片描述
尾節點:
在這里插入圖片描述
很是完美!!!

完整代碼

package com.guqueyue.aHaAlgorithm.chapter_2_StackAndChainTable;import java.util.Scanner;/*** @Author: guqueyue* @Description: 用數組模擬鏈表* @Date: 2024/1/15**/
public class ChainTableTest2 {// 用于控制臺輸入private static Scanner scanner = new Scanner(System.in);private static int[] data = new int[101]; // 元素數組private static int[] right = new int[101]; // 索引數組private static int n = 0; // 鏈表長度public static void main(String[] args) {// 創建鏈表createChainTable();// 打印鏈表printChainTable();// 往鏈表中插入數據
//        insertChainTable();insertChainTable2();// 打印鏈表printChainTable();}/*** @Description 打印鏈表* @return void**/private static void printChainTable() {// 輸出int t = 0;System.out.print("鏈表為:" + data[t]);while(right[t] != -1) {t = right[t]; // 獲取下一個元素的索引System.out.print("->" + data[t]);}System.out.println();}/*** @Description 插入鏈表* @return void**/private static void insertChainTable() {// 插入一個數int len = n;System.out.print("請輸入插入的數:");data[len] = scanner.nextInt();// 按照鏈表順序遍歷 data 數組,找到比 num 大的數int t = 0;while (t != -1) {if (data[right[t]] > data[len]) { // 如果當前節點的下一個節點大于插入數,則插入right[len] = right[t]; // 插入的節點 指向當前節點的下一個節點right[t] = len; // 當前節點 指向插入的節點break;}t = right[t];}}/*** @Description 按照從小到大的順序插入鏈表* @return void**/private static void insertChainTable2() {// 插入一個數int len = n;System.out.print("請輸入插入的數:");data[len] = scanner.nextInt();// 如果新插入的節點比 頭節點 小,則插入到鏈表頭部if (data[len] < data[0]) {// 頭節點和尾節點互換int temp = data[0]; data[0] = data[len]; data[len] = temp;right[len] = right[0]; // 保持舊頭節點原有的連接關系不變right[0] = len; // 將新的頭節點指向舊的節點}else {// 按照鏈表順序遍歷 data 數組,找到比 num 大的數int t = 0;while (right[t] != -1) {if (data[right[t]] > data[len]) { // 如果當前節點的下一個節點大于插入數,則插入right[len] = right[t]; // 插入的節點 指向當前節點的下一個節點right[t] = len; // 當前節點 指向插入的節點break;}t = right[t];}// 插入的數如果比鏈表的最后一個節點大,則插入到鏈表尾部if (right[t] == -1) {right[n-1] = len;right[len] = -1;}}}/*** @Description 創建鏈表* @return void**/private static void createChainTable() {System.out.print("請輸入數字個數: ");n = scanner.nextInt();System.out.printf("請輸入%d個數,中間用空格隔開,輸入完回車: ", n);for (int i = 0; i < n; i++) {data[i] = scanner.nextInt();}// 初始化right數組for (int i = 0; i < n; i++) {right[i] = i == n-1 ? -1 : i+1;}}
}

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

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

相關文章

【C++】string 類 ( 上)

標準庫中的string類 注意&#xff1a; 1. string是表示字符串的字符串類 2. 該類的接口與常規容器的接口基本相同&#xff0c;再添加了一些專門用來操作string的常規操作。 比特就業課 3. string在底層實際是&#xff1a;basic_string模板類的別名&#xff0c;typedef basi…

python爬蟲之selenium知識點記錄

selenium 一、前期準備 1、概述 selenium本身是一個自動化測試工具。它可以讓python代碼調用瀏覽器。并獲取到瀏覽器中加載的各種資源。 我們可以利用selenium提供的各項功能。 幫助我們完成數據的抓取。 2、學習目標 掌握 selenium發送請求&#xff0c;加載網頁的方法 掌…

Stable-Diffusion ubuntu服務器部署,報錯解決方法(小白教程)

Stable Diffusion是一個深度學習模型&#xff0c;專注于生成高質量的圖像。它由CompVis團隊與Stability AI合作開發&#xff0c;并在2022年公開發布。這個模型使用文本提示&#xff08;text prompts&#xff09;生成詳細、逼真的圖像&#xff0c;是目前人工智能圖像生成領域的一…

逆向案例四:360k靜態和精靈數據動態AES解密,用js的方法

一、360K 網頁鏈接:https://www.36kr.com/p/2672600261670407 頁面中有靜態的需要解密的內容&#xff0c;確定html包&#xff0c;確定方法 1.1方法步驟 在下方的搜索中輸入decrypt(或者關鍵字window.initialState &#xff0c;進入js文件 在AES.decrypt處打上斷點&#xff0…

機器學習-03-機器學習算法流程

總結 本系列是機器學習課程的第02篇&#xff0c;主要介紹機器學習中專家系統的應用介紹 本門課程的目標 完成一個特定行業的算法應用全過程&#xff1a; 定義問題&#xff08;Problem Definition&#xff09; -> 數據收集(Data Collection) -> 數據分割(Dataset Spit…

[LeetBook]【學習日記】類鏈表反轉——尋找倒數第cnt個元素

來源于「Krahets」的《圖解算法數據結構》 https://leetcode.cn/leetbook/detail/illustration-of-algorithm/ 題目描述 訓練計劃 II 給定一個頭節點為 head 的鏈表用于記錄一系列核心肌群訓練項目編號&#xff0c;請查找并返回倒數第 cnt 個訓練項目編號。 示例 1&#xff1…

守護無價數據:文件備份的重要性與實用策略

一、數據安全&#xff1a;為何文件備份至關重要 在數字化時代&#xff0c;我們的生活和工作越來越離不開電子設備與其中的文件數據。這些文件可能包含重要的工作文檔、珍貴的家庭照片、個人的創意作品等&#xff0c;它們是我們回憶的載體&#xff0c;也是我們工作和創新的基石…

PDF Expert for Mac v3.9.2中文激活版下載

PDF Expert for Mac是一款易于使用的 PDF 編輯器和注釋器&#xff0c;專為 Mac 設備設計。它允許用戶輕松查看、編輯、簽名、注釋和共享 PDF。該軟件使用戶能夠向他們的 PDF 添加文本、圖像、鏈接和形狀&#xff0c;突出顯示和標記文本&#xff0c;填寫表格以及簽署數字文檔。它…

金融行業專題|期貨超融合架構轉型與場景探索合集(2023版)

更新內容&#xff1a; 更新 SmartX 超融合在期貨行業的覆蓋范圍、部署規模與應用場景。新增 CTP 主席系統實踐與評測、容器云資源池等場景實踐。更多超融合金融核心生產業務場景實踐&#xff0c;歡迎下載閱讀電子書《SmartX 金融核心生產業務場景探索文章合集》。 面對不斷變…

Golang中的四個括號

代碼如下&#xff0c;首先第一個括號內容為wk *worker表示這個函數是一個方法&#xff0c;屬于結構體worker的方法&#xff0c;第二個括號內容為say string&#xff0c;是方法的參數&#xff0c;第三個括號內容err error是方法的返回值&#xff0c;第四個括號是work方法內部的匿…

mac iNode 斷開后沒網 經測試 后臺還在運行

界面斷開&#xff0c;但是連不上網&#xff1a;實際上可能是服務在后臺還在運行 解決方式&#xff1a;終端執行命令 &#xff0c;手動停止iNode服務 sudo /Library/StartupItems/iNodeAuthService/iNodeAuthService stop 停掉之后&#xff0c;有可能連不上網&#xff0c;斷開wi…

基于springboot+vue的美食推薦商城

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

網工必懂的ICMP協議

福建廈門微思網絡始于2002年&#xff0c;面向全國招生&#xff01; 主要課程&#xff1a;華為、思科、紅帽、Oracle、VMware、CISP安全系列、PMP....... 網絡工程師實用課程華為HCIA課程介紹 網絡工程師使用課程華為HCIP課程介紹 網絡工程師使用課程華為HCIE課程介紹 因特網…

更詳細的軟件測試理論基礎:流程,開發、測試模型,測試分類,測試用例及其設計方法,缺陷

文章目錄 一、測試流程二、開發模型1、 瀑布模型2、增量模型3、快速模型4、其他 三、測試模型1、V模型2、W模型 四、測試分類五、測試用例 test case六、測試用例設計方法1、等價類劃分法2、邊界值分析法3、因果圖法4、判定表法5、正交法6、場景法7、流程分析法8、錯誤推測法方…

數據分析-Pandas數據的探查面積圖

數據分析-Pandas數據的探查面積圖 數據分析和處理中&#xff0c;難免會遇到各種數據&#xff0c;那么數據呈現怎樣的規律呢&#xff1f;不管金融數據&#xff0c;風控數據&#xff0c;營銷數據等等&#xff0c;莫不如此。如何通過圖示展示數據的規律&#xff1f; 數據表&…

第16章-DNS

目錄 1. 域名 1.1 產生背景 1.2 概述 1.3 域名的樹形層次化結構 2. DNS 2.1 概述 2.2 工作機制 3. DNS查詢模式 3.1 遞歸查詢&#xff1a; 3.2 迭代查詢&#xff1a; 4. 相關知識點 4.1 集中式DNS 4.2 國內通用DNS 4.3 配置DNS代理 1. 域名 1.1 產生背景 ① IP…

【Excel PDF 系列】iText 庫直接實現表格 PDF

你知道的越多&#xff0c;你不知道的越多 點贊再看&#xff0c;養成習慣 如果您有疑問或者見解&#xff0c;歡迎指教&#xff1a; 企鵝&#xff1a;869192208 文章目錄 前言生成表格 PDF 效果引入 pom 配置代碼實現定義 CreateExcelToPdfModel 對象主方法 前言 最近遇到生成 E…

Java必須掌握的繼承中的構造方法和this super關鍵字(含面試大廠題和源碼)

在Java中&#xff0c;繼承中的構造方法和關鍵字this、super是面試中經常涉及的重要話題。下面是一個潛在的大廠面試題&#xff0c;以及可能的解答和討論。 面試題&#xff1a; 請解釋Java中繼承中構造方法的作用以及關鍵字this和super的使用場景。請提供示例代碼加以說明。 …

EchoServer回顯服務器簡單測試

目錄 工具介紹 工具使用 測試結果 工具介紹 github的一個開源項目,是一個測壓工具 EZLippi/WebBench: Webbench是Radim Kolar在1997年寫的一個在linux下使用的非常簡單的網站壓測工具。它使用fork()模擬多個客戶端同時訪問我們設定的URL&#xff0c;測試網站在壓力下工作的…

ARMv8-A電源管理Power management

目錄 一、ARMv8-A電源管理概述 二、idle管理 2.1 電源和時鐘 Standby-待機 Retention-保持 Powerdown-關機 Dormant mode-休眠模式 Hotplug-熱插拔 三、動態電壓和頻率調節 四、匯編語言power指令 五、電源狀態協調接口 一、ARMv8-A電源管理概述 許多ARM系統是移動…