數據結構Java實現----鏈表

来源:https://www.cnblogs.com/xiaoxu-xmy/archive/2018/07/20/9337161.html
-Advertisement-
Play Games

MyLinkList類 1 package List; 2 3 // 單向鏈表 4 public class MyLinkList { 5 private Node root; // 根結點 6 private int size; // 結點個數 7 private int index; // 腳標 ...


一.單向鏈表(遞歸)

MyLinkList類

  1 package List;
  2 
  3 // 單向鏈表
  4 public class MyLinkList {
  5     private Node root; // 根結點
  6     private int size; // 結點個數
  7     private int index; // 腳標
  8     private Object[] reData; // 保存數據的數組
  9 
 10     // 構造方法
 11     public MyLinkList() {
 12         this.root = new Node("head");
 13         System.out.println("創建了帶頭指針的鏈表");
 14     }
 15 
 16     public MyLinkList(Object data) {
 17         if (data == null)
 18             System.out.println("參數錯誤");
 19         this.root = new Node(data);
 20         this.size++;
 21         System.out.println("創建成功" + data);
 22     }
 23 
 24     // 是否是空表
 25     public boolean isEmpty() {
 26         return this.size == 0;
 27     }
 28 
 29     // 返回長度
 30     public int size() {
 31         return this.size;
 32     }
 33     
 34     // 清空鏈表
 35     public void clear(){
 36         this.root = null;
 37         this.size = 0;
 38     }
 39 
 40     // 判斷兩個鏈表是否相等
 41     public boolean equals(Object obj){
 42         // 常規判斷
 43         if(obj == null)
 44             return false;
 45         if(obj == this)
 46             return true;
 47         
 48         // 是MyLinkList類
 49         if(obj instanceof MyLinkList){
 50             MyLinkList linkList = (MyLinkList)obj;
 51             
 52             // 根結點相同
 53             if(!this.root.data.equals(linkList.root.data)){
 54                 System.out.println("根節點不相同");
 55                 return false;
 56             }
 57             // 長度相同
 58             if(this.size != linkList.size) {
 59                 System.out.println("長度不同");
 60                 return false;
 61             }
 62             
 63             // 各個結點相同
 64             if(this.size==1){ // 只含有根結點
 65                 return true;
 66             }
 67             return this.root.next.equals(linkList.root.next);
 68         }
 69         
 70         // 不是MyLinkList類
 71         return false;
 72             
 73     }
 74 
 75     // 添加單個數據
 76     public boolean addData(Object data) {
 77         if (data == null) {
 78             System.out.println("參數錯誤");
 79             return false;
 80         }
 81 
 82         // 把data封裝成帶指針域的結點
 83         Node node = new Node(data);
 84 
 85         if (this.root.next == null)
 86             this.root.next = node;
 87         else
 88             this.root.next.addNode(node);
 89         System.out.println("添加成功" + data);
 90         this.size++;
 91         return true;
 92     }
 93 
 94     // 添加多個數據
 95     public boolean addDatas(Object[] datas) {
 96         if (datas == null) {
 97             System.out.println("參數錯誤");
 98             return false;
 99         }
100 
101         // 迴圈添加結點
102         for (int index = 0; index < datas.length; ++index) {
103             Node data = new Node(datas[index]);// 封裝結點
104             this.root.addNode(data);
105             this.size++;
106         }
107         return true;
108     }
109 
110     // 查找數據是否存在
111     public boolean contains(Object data) {
112         if (data == null || this.isEmpty())
113             return false;
114         return this.root.containsNode(data);
115     }
116 
117     // 查找指定位置下的數據
118     public Object get(int index) {
119         // 參數錯誤
120         if (this.isEmpty() || index < 0 || index > this.size)
121             return null;
122 
123         if (this.root.data.equals("head")) { // 帶頭指針
124             if (index == 1) // 返回第一個有效數據
125                 return this.root.next.data;
126             else {
127                 this.index = 0;
128                 return this.root.next.getNode(index);
129             }
130         } else { // 不帶頭指針
131             if (index == 1) // 返回第一個有效數據
132                 return this.root.data;
133             else {
134                 this.index = 1;
135                 return this.root.next.getNode(index);
136             }
137 
138         }
139     }
140 
141     // 刪除數據
142     public boolean deleteData(Object data) {
143         if (data == null || this.isEmpty()) {
144             return false;
145         }
146         // 是根結點
147         if (this.root.data.equals(data)) {
148             this.root = this.root.next;
149             this.size--;
150             return true;
151         }
152 
153         // 不是根節點
154         else
155             return this.root.deleteNode(data);
156     }
157 
158     // 列印所有數據
159     public void print() {
160         if (this.isEmpty())
161             System.out.print("空表--------");
162         else
163             this.root.printNode();
164         System.out.println("");
165     }
166 
167     // 返回數組數據
168     public Object[] toArray() {
169         if (this.isEmpty())
170             return null;
171 
172         // 數組保存
173         this.index = 0; // 數組下標
174         if (this.root.data.equals("head")) // 鏈錶帶頭指針
175             reData = new Object[++this.size];
176         else
177             reData = new Object[this.size];
178         this.root.toArray();
179         return reData;
180     }
181 
182     // 結點類(內部)
183     class Node {
184         Object data; // 數據域
185         Node next; // 指針域
186 
187         // 構造方法
188         public Node(Object data) {
189             this.data = data;
190         }
191 
192         // 添加結點
193         public void addNode(Node node) {
194             if (this.next == null)
195                 this.next = node;
196             else
197                 this.next.addNode(node);
198         }
199 
200         // 列印結點數據
201         public void printNode() {
202             System.out.print(this.data + " ");
203             if (this.next != null)
204                 this.next.printNode();
205         }
206 
207         // 刪除結點
208         public boolean deleteNode(Object data) {
209             if (this.next == null) {
210                 System.out.println("刪除失敗" + data);
211                 return false;
212             }
213             if (this.next.data.equals(data)) {
214                 System.out.println("刪除成功" + this.next.data);
215                 MyLinkList.this.size--;
216                 this.next = this.next.next;
217                 return true;
218             }
219             return this.next.deleteNode(data);
220         }
221 
222         // 返回數組
223         public void toArray() {
224             MyLinkList.this.reData[MyLinkList.this.index++] = this.data;
225             if (this.next != null)
226                 this.next.toArray();
227         }
228 
229         // 查找指定結點
230         public Object getNode(int index) {
231             if (++MyLinkList.this.index == index)
232                 return this.data;
233             return this.next.getNode(index);
234         }
235 
236         // 查找結點
237         public boolean containsNode(Object data) {
238             if (this.data == data)
239                 return true;
240             if (this.next != null)
241                 return this.next.containsNode(data);
242             return false;
243         }
244         
245         // 重寫equals()
246         public boolean equals(Node node){
247             // 數據域是否相同
248             if(!this.data.equals(node.data)) {
249                 System.out.println("數據域不同this:"+this.data+" linkList:"+node.data);
250                 return false;
251             }
252             // 還有下個結點
253             if(this.next!=null)
254                 return this.next.equals(node.next);
255             // 沒有下個結點且到目前為止所有結點數據域相同
256             return true;
257             
258         }
259     }
260 }
MyLinkList

TestMyLinkList類

 1 package List;
 2 
 3 // 單向鏈表測試
 4 public class TestMyLinkList {
 5 
 6     public static void main(String[] args) {
 7         // 創建一個鏈表
 8         MyLinkList linkList = new MyLinkList(5);
 9 
10         // 初始化一個鏈表
11         for (int index = 1; index < 10; ++index) {
12             int num = (int) (Math.random() * 11);
13             linkList.addData(num);
14         }
15 
16         // 列印鏈表的所有數據
17         linkList.print();
18 
19         // 刪除結點
20         linkList.deleteData(5);
21         linkList.print();
22         linkList.deleteData(10);
23         linkList.print();
24 
25         System.out.println("第2個結點數據:" + linkList.get(2));
26         // 數組化
27         Object[] data = new Object[linkList.size()];
28         data = linkList.toArray();
29         for (Object index : data)
30             System.out.print(index + " ");
31         System.out.println("");
32         System.out.println("-------------------");
33         // 創建一個鏈表
34         MyLinkList linkList2 = new MyLinkList();
35 
36         // 待添加數據的數組
37         Object[] datas = { 5, "123", 26 };
38         linkList2.addDatas(datas);
39         System.out.println("包含'5'嗎" + linkList2.contains(5));
40         linkList2.print();
41         System.out.println("----------------------------");
42         // 創建一個鏈表
43         MyLinkList linkList1 = new MyLinkList();
44         linkList1.addDatas(datas);
45         linkList1.print();
46         System.out.println("是否相等"+linkList2.equals(linkList1));
47     }
48 
49 }
TestMyLinkList

列印

 1 添加成功5
 2 添加成功1
 3 添加成功6
 4 添加成功6
 5 添加成功6
 6 添加成功1
 7 添加成功5
 8 添加成功2
 9 添加成功10
10 5 5 1 6 6 6 1 5 2 10 
11 5 1 6 6 6 1 5 2 10 
12 刪除成功10
13 5 1 6 6 6 1 5 2 
14 第2個結點數據:1
15 5 1 6 6 6 1 5 2 
16 -------------------
17 包含'5'嗎true
18 head 5 123 26 
19 ----------------------------
20 head 5 123 26 
21 是否相等true
TestMyLinkList-console

總結:1.避免空指針異常(NullPointException):先判斷引用是否為null,後使用。

參考:https://www.cnblogs.com/dolphin0520/p/3811445.html

2018-7-19

二、雙向鏈表(迴圈、頭插法)

DoubleLink類

  1 package List;
  2 
  3 // 雙向鏈表(循壞、頭插法)
  4 public class DoubleLink {
  5     private Node root; // 表頭
  6     private int size; // 長度
  7 
  8     // 結點類
  9     private class Node {
 10         Object data; // 數據域
 11         Node prev; // 前趨
 12         Node next; // 後繼
 13 
 14         // 構造方法
 15         public Node(Object data, Node prev, Node next) {
 16             this.data = data;
 17             this.prev = prev;
 18             this.next = next;
 19         }
 20 
 21         public Node(Object data) {
 22             this.data = data;
 23         }
 24     }
 25 
 26     // 構造方法
 27     public DoubleLink() {
 28         this.root = new Node(null, null, null);
 29         this.root.prev = this.root.next = this.root;
 30         this.size = 0;
 31     }
 32 
 33     // 是否是空表
 34     public boolean isEmpty() {
 35         return this.size == 0;
 36     }
 37 
 38     // 返回長度
 39     public int size() {
 40         return this.size;
 41     }
 42 
 43     // 添加數據
 44     public boolean addData(Object data) {
 45         // 空引用
 46         if (data == null)
 47             return false;
 48 
 49         this.size++; // 增加長度
 50         Node node = new Node(data); // 封裝結點
 51         // 添加結點
 52 
 53         if (this.isEmpty()) {
 54             this.root.next = node;
 55             this.root.prev = node;
 56 
 57             node.next = this.root;
 58             node.prev = this.root;
 59             return true;
 60         }
 61 
 62         // 頭插法
 63         node.next = this.root.next; // 將新結點的後繼指向頭結點的後繼
 64         node.prev = this.root; // 將新結點的前驅指向頭結點
 65         this.root.next.prev = node; // 頭結點的後繼結點的前驅指向新結點
 66         this.root.next = node; // 頭結點的後繼節點指向新結點
 67         return true;
 68     }
 69 
 70     // 查找第index結點
 71     private Node getNode(int index) {
 72         Node oldNode = this.root;
 73         int foot = 0; // 腳標
 74         if (index <= this.size / 2) { // 正查找
 75             System.out.print("正查");
 76             while (true) {
 77                 if (foot++ == index)
 78                     break;
 79                 oldNode = oldNode.next;
 80             }
 81         } else {
 82             int LIndex = this.size + 1 - index;
 83             System.out.print("反查");
 84             while (true) {
 85                 if (foot++ == LIndex)
 86                     break;
 87                 oldNode = oldNode.prev;
 88             }
 89         }
 90         System.out.print(oldNode.data);
 91         return oldNode;
 92     }
 93 
 94     // 查找結點
 95     private Node getNode(Object data) {
 96         Node oldNode = this.root.next;
 97         while (true) {
 98             if (oldNode.data.equals(data))
 99                 return oldNode;
100             if (oldNode.next.data == null)
101                 return null;
102             oldNode = oldNode.next;
103         }
104 
105     }
106 
107     // 刪除結點
108     private void removeNode(Node node) {
109         node.next.prev = node.prev; // 結點的後繼結點的前驅指向結點的前驅
110         node.prev.next = node.next; // 結點的前驅結點的後繼指向結點的後繼
111         node = null;
112     }
113 
114     // 前插法
115     private boolean addNode(Node oldNode, Node newNode) {
116         oldNode.prev.next = newNode;
117         newNode.prev = oldNode.prev;
118         oldNode.prev = newNode;
119         newNode.next = oldNode;
120         return true;
121     }
122 
123     // 在index結點前插入新結點
124     public boolean addData(Object data, int index) {
125         if (data == null)
126             return false;
127         if (index <= 0 || index > this.size)
128             return false;
129 
130         Node newNode = new Node(data); // 封裝結點
131 
132         // 查找結點
133         Node oldNode = getNode(index);
134         this.size++; // 增加長度
135         // 更改指針域
136         return addNode(oldNode, newNode);
137     }
138 
139     // 得到第index個結點的數據
140     public Object get(int index) {
141         if (this.isEmpty())
142             return null;
143         if (index <= 0 || index > this.size)
144             return null;
145 
146         // 查找結點
147         return getNode(index).data;
148     }
149 
150     	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、 集合的嵌套: 集合的用法其實和數組的用法有很多共同之處,在使用數組的時候,二維數組就是數組的嵌套; 那麼在集合之中是否也可以這樣呢? 當然也是可以的,例如對於最複雜的的map集合; map<string, map<string,student>>;這樣map中就嵌套了一個map集合; 其中對於 ...
  • “Spring”——每一個Javaer開發者都繞不開的字眼,從21世紀第一個十年國內異常活躍的SSH框架,到現在以Spring Boot作為入口粘合了各種應用。Spring現在已經完成了從web入口到微服務架構再到數據處理整個生態,看著現在https://spring.io/projects上長長的 ...
  • @Controller @Controller 註解用於標記在 Java 類上。被 @Controller 標記過的類就是一個 SpringMVC Controller對象。DispatcherServlet 會掃描使用了該註解的類的方法,並檢查對應方法是否有 @RequestMapping 註解標 ...
  • 編寫此文僅為以後可以複習。 最近在自學Java核心技術(很好的書,推薦!!),也是第一次從上面瞭解了goto,或許只是淺層瞭解。 錯誤之處希望大佬們給予批評與建議!!謝謝!!! Java核心技術中就提到過:無限制的使用goto語句確實是導致錯誤的根源,但是有些情況下,偶爾使用goto 跳出迴圈 還是 ...
  • 1、三層架構 表現層 web層(MVC是一個表現層的設計模型) 業務層 service層 持久層 dao層2、三大框架和三層架構的關係(建議學習三大框架的順序:先學習hibernate在學習struts2框架,最後學習spring 框架) hibernate框架:它是一個持久層框架 struts2框 ...
  • 前言 作為一名準備轉行數據分析的小白,我先接觸到的是網路爬蟲學習,每次爬蟲運行都有新的bug收穫,通過不斷debug,終於稍微能爬一些數據了,在此想和大家分享一下~ 私信小編007即可獲取小編精心準備的PDF十套哦! 看看最後一頁搜索結果 。 PS:小技巧,在頁面下部跳轉頁面輸入一個很大的數字,比如 ...
  • 在使用 Spring Cloud 體系來構建微服務的過程中,用戶請求是通過網關(ZUUL 或 Spring APIGateway)以 HTTP 協議來傳輸信息,API 網關將自己註冊為 Eureka 服務治理下的應用,同時也從 Eureka 服務中獲取所有其他微服務的實例信息。搭建 OAuth2 認... ...
  • 封裝將內部細節封裝起來,只暴露外部介面。 比如我們的電視就將複雜的內部線路用外殼封裝起來,只留下外部按鈕或遙控,用戶只需要知道按鈕或遙控的作用就可以,無需明白電視內部是如何工作。 而且封裝也保障了安全性,用戶只能去使用暴露在外部的介面,不能改變內部結構,保障了正常運行。 封裝後,使用者不必知曉複雜的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...