【数据结构基础】之链表介绍,生动形象,通俗易懂,算法入门必看
前言
本文為 數據結構基礎【鏈表】 相關知識,下邊將對鏈表概念,單鏈表,雙鏈表,循環鏈表,Java中鏈表的使用等進行詳盡介紹~
📌博主主頁:′Code_Wang的主頁
👉Java全棧學習路線可參考:【Java全棧學習路線】最全的Java學習路線及知識清單,Java自學方向指引,內含最全Java全棧學習技術清單~
👉算法刷題路線可參考:算法刷題路線總結與相關資料分享,內含最詳盡的算法刷題路線指南及相關資料分享~
目錄
【數據結構基礎】鏈表
- 前言
- 目錄
- 一、鏈表介紹
- 二、單鏈表
- 三、雙鏈表
- 四、循環鏈表
- 五、封裝一個超級鏈表
- 六、Java中鏈表的使用
- 1??Java中LinkedList的操作
- 2??Java實現鏈表
- 后記
一、鏈表介紹
- 在內存空間中,數組和鏈表都是基本的數據結構,都是【表】,或者叫【線性表】。
- 線性表是一個線性結構,它是一個含有n≥0個結點的有限序列,對于其中的結點,有且僅有一個開始結點沒有前驅但有一個后繼結點,有且僅有一個終端結點沒有后繼但有一個前驅結點,其它的結點都有且僅有一個前驅和一個后繼結點,說人話,就是有頭有尾一條線。
還不明白就再來一張圖:
- 鏈表是一種動態數據結構,他的特點是用一組任意的存儲單元(可以是連續的,也可以是不連續的)存放 數據元素。
- 鏈表中每一個元素成為 “結點” , 每一個結點都是由數據域和指針域組成的, 每個結點中的指針域指向下一 個結點。
- Head 是 “頭指針” , 表示鏈表的開始, 用來指向第一個結點, 而最后一個指針的指針域為 NULL( 空地址 ) ,表示鏈表的結束。
- 可以看出鏈表結構必須利用指針才能實現,即一個結點中必須包含一個指針變量,用來存放下一個結點的 地址。
- 實際上,鏈表中的每個結點可以用若干個數據和若干個指針。
二、單鏈表
單鏈表特點:
- 長度可變,擴展性好
- 內存利用高(可以不連續)
- 時間性能:查找O(n)、插入和刪除O(1)
- 空間性能:不需要分配存儲空間,只要有就可以分配,元素個數不受限制
單鏈表的邏輯結構:
單向鏈表的節點的抽象:
其節點由兩部分構成:
- data域:數據域,用來存儲元素數據
- next域:用于指向下一節點
三、雙鏈表
單向鏈表的缺點分析:
- 單向鏈表,查找的方向只能是一個方向,而雙向鏈表可以向前或者向后查找。
- 單向鏈表不能自我刪除,需要靠輔助節點 ,而雙向鏈表,則可以自我刪除,所以前面我們單鏈表刪除時節點,總是找到temp,temp是待刪除節點的前一個節點
為了能夠實現雙向查找的和自我刪除的功能,引出了雙向鏈表的概念。
雙向鏈表的邏輯結構:
雙向鏈表的節點的抽象:
其節點由三部分構成:
- data域:數據域,用來存儲元素數據
- next域:用于指向后一節點
- front域:用于指向前一節點
四、循環鏈表
鏈表的最后一個節點指向第一個節點,整體構成一個鏈環。
將單鏈表中的終端結點的指針端由空指針改為指向頭結點,就使整個單鏈表形成一個環,這種頭尾相接的單鏈表稱為單循環鏈表,簡稱 循環鏈表(circular linked list),循環鏈表不一定需要頭結點???????。
五、封裝一個超級鏈表
寫鏈表首先要封裝一個保存數據和引用的節點,俗稱node
public class Node {private Integer data;private Node next;public Integer getData() {return data;}public void setData(Integer data) {this.data = data;}public Node getNext() {return next;}public void setNext(Node next) {this.next = next;} }封裝一個超級鏈表
public class SuperLinked {// 鏈表的長度private int size;// 維護一個頭節點private Node first;// 維護一個尾節點private Node last;// 無參構造器public SuperLinked(){}//添加元素至鏈表尾部public boolean add(Integer data){Node node = new Node(data,null);if (first == null){first = node;} else {last.setNext(node);}last = node;size++;return true;}//在指定下標添加元素public boolean add(int index,Integer data){Node node = getNode(index);Node newNode = new Node(data,null);if (node != null){newNode.setNext(node.getNext());node.setNext(newNode);} else {first = newNode;last = newNode;}size++;return true;}// 刪除頭元素public boolean remove(){if (size < 0){return false;}if (first != null ){first = first.getNext();size--;}return true;}// 刪除指定元素public boolean remove(int index){if (size < 0){return false;}if(size == 1){first = null;last = null;} else {Node node = getNode(index-1);node.setNext(node.getNext().getNext());}size--;return true;}// 修改指定下標的元素public boolean set(int index,Integer data){// 找到第index個Node node = getNode(index);node.setData(data);return true;}// 獲取指定下標的元素public Integer get(int index){return getNode(index).getData();}//查看當前有多少個數字public int size(){return size;}//添加元素private Node getNode(int index){// 邊界判斷if(index <= 0){index = 0;}if(index >= size-1){index = size-1;}// 找到第index個Node cursor = first;for (int i = 0; i < index; i++) {cursor = cursor.getNext();}return cursor;}public static void main(String[] args) {SuperLinked linked = new SuperLinked();linked.add(1);linked.add(2);linked.add(4);linked.add(6);linked.add(3);linked.add(2);linked.add(7);linked.add(6);linked.remove();linked.remove(2);linked.set(0,3);for (int i = 0; i < linked.size(); i++) {System.out.println(linked.get(i));}} }六、Java中鏈表的使用
- ArrayList和LinkedList都實現了鏈表,兩者的區別在于與 ArrayList 相比,LinkedList的增加和刪除的操作效率更高,而查找和修改的操作效率較低。
- 鏈表用LinkedList較多。
1??Java中LinkedList的操作
LinkedList 類位于 java.util 包中,使用前需要引入它,語法格式如下:
// 引入 LinkedList 類 import java.util.LinkedList; LinkedList<E> list = new LinkedList<E>(); // 普通創建方法 // 或者 LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合創建鏈表創建一個簡單的鏈表實例:
import java.util.LinkedList;public class RunoobTest {public static void main(String[] args) {LinkedList<String> sites = new LinkedList<String>();sites.add("Google");sites.add("Runoob");sites.add("Taobao");sites.add("Weibo");System.out.println(sites);} }以上鏈表實例的執行輸出結果為:
// 打印結果: [Google, Runoob, Taobao, Weibo]LinkedList的其他操作:
| addFirst() | 在表頭增加一個元素 |
| addLast() | 在表尾增加一個元素 |
| removeFirst() | 從表頭移除一個元素 |
| removeLast() | 從表尾移除一個元素 |
| getFirst() | 獲得表頭的元素 |
| getLast() | 獲得表尾的元素 |
2??Java實現鏈表
java中ListNode鏈表就是用Java自定義實現的鏈表結構。
基本結構:
class ListNode { //類名 :Java類就是一種自定義的數據結構int val; //數據 :節點數據 ListNode next; //對象 :引用下一個節點對象。在Java中沒有指針的概念,Java中的引用和C語言的指針類似 }添加構造方法方便初始化:
class ListNode { //類名 :Java類就是一種自定義的數據結構int val; //數據 :節點數據 ListNode next; //對象 :引用下一個節點對象。在Java中沒有指針的概念,Java中的引用和C語言的指針類似ListNode(int val){ //構造方法 :構造方法和類名相同 this.val=val; //把接收的參數賦值給當前類的val變量} }范型寫法,使用范型可以兼容不同的數據類型:
class ListNode<E>{ //類名 :Java類就是一種自定義的數據結構E val; //數據 :節點數據 ListNode<E> next; //對象 :引用下一個節點對象。在Java中沒有指針的概念,Java中的引用和C語言的指針類似ListNode(E val){ //構造方法 :構造方法和類名相同 this.val=val; //把接收的參數賦值給當前類的val變量} }創建鏈表及遍歷鏈表:
class ListNode { //類名 :Java類就是一種自定義的數據結構int val; //數據 :節點數據 ListNode next; //對象 :引用下一個節點對象。在Java中沒有指針的概念,Java中的引用和C語言的指針類似ListNode(int val){ //構造方法 :構造方法和類名相同 this.val=val; //把接收的參數賦值給當前類的val變量} }class Test{public static void main(String[] args){ListNode nodeSta = new ListNode(0); //創建首節點ListNode nextNode; //聲明一個變量用來在移動過程中指向當前節點nextNode=nodeSta; //指向首節點//創建鏈表for(int i=1;i<10;i++){ListNode node = new ListNode(i); //生成新的節點nextNode.next=node; //把心節點連起來nextNode=nextNode.next; //當前節點往后移動} //當for循環完成之后 nextNode指向最后一個節點,nextNode=nodeSta; //重新賦值讓它指向首節點print(nextNode); //打印輸出}//打印輸出方法static void print(ListNode listNoed){//創建鏈表節點while(listNoed!=null){System.out.println("節點:"+listNoed.val);listNoed=listNoed.next;}System.out.println();}}插入節點:
替換節點:
刪除節點:
在對節點進行替換或刪除的時候,被替換或被刪節點的next引用需不需要設置為null?
答案是: 不需要,因為一個對象被回收的前提是因為沒有任何地方持有這個對象的引用(引用計數器為0)也就是說它不在被引用,那么那么它將被回收,至于它引用什么對象無關緊要,因為對于它所引用的對象來說依然是看引用計數器是否為0。
后記
👉Java全棧學習路線可參考:【Java全棧學習路線】最全的Java學習路線及知識清單,Java自學方向指引,內含最全Java全棧學習技術清單~
👉算法刷題路線可參考:算法刷題路線總結與相關資料分享,內含最詳盡的算法刷題路線指南及相關資料分享~
總結
以上是生活随笔為你收集整理的【数据结构基础】之链表介绍,生动形象,通俗易懂,算法入门必看的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 专访轻奢手机品牌HANMAC钱总:为何选
- 下一篇: mac 下面 you have an o