視頻書籍哪裏找?
微信關注公衆號「小魚與Java」,後臺回覆數據結構
,有我已經整理好的資料。
java
物理結構就是數據在磁盤上的存儲方式,能夠是一整塊存儲區域,也能夠是不一樣的存儲塊(可是它們以前有關係,因此就劃分爲一組數據)。node
就是在磁盤上連續存儲的,在Java中就是數組,它從第一個索引開始,全部的數據都是緊跟其後的。程序員
這些數據(稱爲數據元素,是不可再分隔的)在磁盤上是分開存儲的,只是由於它們之間有一些關係,因此咱們就將其聯繫到了一塊兒,組成了一種數據結構————鏈表。編程
就是在這個元素中,除了存儲它自身的數據還存儲了它的下一個數據
api
class LinkedNode<T> { private T data; private LinkedNode<T> next; public LinkedNode(T data) { this.data = data; //在構建這個時,咱們就讓它的下一個指針爲null next = null; } }
接下來寫一個管理它的類,咱們寫一個add(T t)方法,就是插入到最後數組
public class MyLinked<T> { /** * 用一個頭指針來表示這個鏈表的頭 */ private LinkedNode<T> first; public MyLinked() { } /** * 提供一個有參構造方法 * * @param t */ public MyLinked(T t) { this.first = new LinkedNode<>(t); first.next=null; } /** * 往鏈表中添加元素,默認是添加到最後的 * * @param t */ public void add(T t) { if (first == null) { first = new LinkedNode<>(t); } else { LinkedNode herd = first; while (herd.next != null) { herd = herd.next; } //當從這個循環中出來的時候,這個herd.next就是null,也就是說這個herd就是這個鏈表的最後一個元素 herd.next = new LinkedNode(t); } } }
咱們寫的這個add方法,是要遍歷整個鏈表來作此操做。
以上就是最簡單的一個鏈表類了,咱們使用了泛型爲了讓其更加通用。微信
雙向鏈表就是在這個鏈表中存儲了自身的數據,還存儲了它的前一個和後一個數據的地址。數據結構
class LinkedNode<T> { private T data; private LinkedNode<T> prev; private LinkedNode<T> next; public LinkedNode(T data) { this.data = data; this.prev = null; this.next = null; } }
private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
咱們主要看一下,它的最基本的add方法,來體驗一個它的魅力編程語言
add(E e)就是添加到鏈表的最後,最終調用的方法以下:學習
void linkLast(E e) { //將當前的最後一個節點保存下來 final Node<E> l = last; //構造一個新的節點對象 final Node<E> newNode = new Node<>(l, e, null); //將這個鏈表的last指向這個新元素 last = newNode; if (l == null){ //這個條件就是說,此時鏈表爲空。由於l是在添加以前的last,若是這個鏈表爲空,last確定是空的 first = newNode; }else{ l.next = newNode; } size++;//當前的鏈表大小++ modCount++;//這個是用來記錄這個鏈表的操做次數,對這個鏈表進行的任何操做,這個都會++ }
上邊的構造方法
Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; }
這個插入到時最後的鏈表並無去遍歷一個整個鏈表,而是將last.next指向了這個新的節點
add(int index, E e)插入到指定位置
這個最重要的就是利用循環列表來找到這個index是在前半邊仍是後半邊,主要尋找的代碼以下:
Node<E> node(int index) { if (index < (size >> 1)) { //上邊的>>就是取半,除以2 Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
能夠看到,它判斷了所在的部分進行了不一樣的遍歷方式,就是對二分法的一次簡利用