视频书籍哪里找?
微信关注公众号“小鱼与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; } }
能够看到,它判断了所在的部分进行了不一样的遍历方式,就是对二分法的一次简利用