前言
鍊錶是一種常見的基礎數據結構,它是一種線性表,但在內存中它並不是順序存儲的,它是以鍊式進行存儲的,每一個節點裡存放的是下一個節點的“指針”。在Java中的數據分為引用數據類型和基礎數據類型,在Java中不存在指針的概念,但是對於鍊錶而言的指針,指的就是引用數據類型的地址。
鍊錶和數組都是線性的數據結構,對於數組而言其長度是固定的,由於在內存中其是連續的,因此更適合做查找與遍歷,而鍊錶在內存中是並不是順序存儲的,但是由於其是通過“指針”構成的,因此在插入、刪除時比較數組更為的方便。
下面的代碼通過內部類並結合遞歸的方式來實現了一個簡單的用Java語言描述的鍊錶的數據結構,下面話不多說了,來一起看看詳細的介紹吧
鍊錶數據結構的定義
首先來看一下,鍊錶數據結構的定義,代碼如下:
class NodeManager { private Node root; // 根節點private int currentIndex = 0; // 節點的序號,每次操作從0開始public void add(int data) {} public void delNode(int data) {} public void print() {} public boolean findNode(int data) {} public boolean updateNode(int oldData, int newData) {} // 向索引之前插入public void insert(int index, int data) {} // 誰擁有數據,誰提供方法class Node { private int data; private Node next; // 把當前類型作為屬性public Node(int data) { this.data = data; } public void setData(int data) { this.data = data; } public int getData() { return data; } // 添加節點public void addNode(int data) {} // 刪除節點public void delNode(int data) {} // 輸出所有節點public void printNode() {} // 查找節點是否存在public boolean findNode(int data) {} // 修改節點public boolean updateNode(int oldData, int newData) {} // 插入節點public void insertNode(int index, int data) {} }}對於鍊錶的定義來說,NodeManager類是用來管理鍊錶操作的,而成員內部類Node是用於提供鍊錶數據與鍊式結構的。對於類的使用者來說,並不直接訪問數據,因此操作的是NodeManager類,而內部類Node提供了真正的數據管理,因此Node類需要提供真正的數據操作方法,對於NodeManager類中也需要提供一套由外部來操作鍊錶的方法。因此,在NodeManager類和Node類中都提供了看似相同的方法,但實際的意義並不相同。
下面來查看NodeManager類和Node類中的add()方法,代碼如下:
public void add(int data) { if ( root == null ) { root = new Node(data); } else { root.addNode(data); }}// 添加節點public void addNode(int data) { if ( this.next == null ) { this.next = new Node(data); } else { this.next.addNode(data); }}代碼中上面的方法是NodeManager類中的方法,而下面的方法是Node類中的方法。
在Manager類中提供了一個root的成員變量,它用於管理鍊錶的頭節點,因此在添加節點時,會先判斷root是否為空,如果為空則直接將節點由root來進行保存,如果root不為空,則通過Node類中的addNode()方法來進行添加,添加到思路是找到當前鍊錶的最後一個節點,並將新添加到節點賦值給最後一個節點的next成員變量中。
鍊錶增刪改查
對於鍊錶的其他操作也是相同的思路,關於鍊錶增刪改查和輸出的完整代碼如下:
class NodeManager { private Node root; // 根節點private int currentIndex = 0; // 節點的序號,每次操作從0開始public void add(int data) { if ( root == null ) { root = new Node(data); } else { root.addNode(data); } } public void delNode(int data) { if ( root == null ) return ; if ( root.getData() == data ) { Node tmp = root; root = root.next; tmp = null; } else { root.delNode(data); } } public void print() { if ( root != null ) { System.out.print(root.getData() + " "); root.printNode(); System.out.println(); } } public boolean findNode(int data) { if ( root == null ) return false; if ( root.getData() == data ) { return true; } else { return root.findNode(data); } } public boolean updateNode(int oldData, int newData) { if ( root == null ) return false; if ( root.getData() == oldData ) { root.setData(newData); return true; } else { return root.updateNode(oldData, newData); } } // 向索引之前插入public void insert(int index, int data) { if ( index < 0 ) return ; currentIndex = 0; if ( index == currentIndex ) { Node newNode = new Node(data); newNode.next = root; root = newNode; } else { root.insertNode(index, data); } } // 誰擁有數據,誰提供方法class Node { private int data; private Node next; // 把當前類型作為屬性public Node(int data) { this.data = data; } public void setData(int data) { this.data = data; } public int getData() { return data; } // 添加節點public void addNode(int data) { if ( this.next == null ) { this.next = new Node(data); } else { this.next.addNode(data); } } // 刪除節點public void delNode(int data) { if ( this.next != null ) { if ( this.next.getData() == data ) { Node tmp = this.next; this.next = this.next.next; tmp = null; } else { this.next.delNode(data); } } } // 輸出所有節點public void printNode() { if ( this.next != null ) { System.out.print(this.next.getData() + " "); this.next.printNode(); } } // 查找節點是否存在public boolean findNode(int data) { if ( this.next != null ) { if ( this.next.getData() == data ) { return true; } else { return this.next.findNode(data); } } return false; } // 修改節點public boolean updateNode(int oldData, int newData) { if ( this.next != null ) { if ( this.next.getData() == oldData ) { this.next.setData(newData); return true; } else { return this.next.updateNode(oldData, newData); } } return false; } // 插入節點public void insertNode(int index, int data) { currentIndex ++; if ( index == currentIndex ) { Node newNode = new Node(data); newNode.next = this.next; this.next = newNode; } else { this.next.insertNode(index, data); } } }}以上就是鍊錶基本操作的完整代碼,下面寫一個調用的代碼進行測試,代碼如下:
public class LinkList { public static void main(String[] args) { NodeManager nm = new NodeManager(); System.out.println("鍊錶的添加(添加5、4、3、2、1)"); nm.add(5); nm.add(4); nm.add(3); nm.add(2); nm.add(1); nm.print(); System.out.println("鍊錶的刪除(刪除3)"); nm.delNode(3); nm.print(); System.out.println("鍊錶的查找(查找1)"); System.out.println(nm.findNode(1)); System.out.println("鍊錶的查找(查找10)"); System.out.println(nm.findNode(10)); System.out.println("鍊錶的更新(把1更新為10)"); nm.updateNode(1, 10); nm.print(); System.out.println("鍊錶的插入(在第1個位置插入20)"); nm.insert(1, 20); nm.print(); System.out.println("鍊錶的插入(在第0個位置插入30)"); nm.insert(0, 30); nm.print(); }}將代碼編譯、運行,結果如下圖:
對於Java中的集合類中用到了不少的數據結構的知識,等自己狀態好的時候學習學習Java集合類的源碼。我會努力做一個初級程序員!
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。