一、双向链表
1.定义:由多个结点组成,每一个结点包含一个数据域和两个指针域,其中一个指针域指向另一个结点的前驱,另一个指针域指向后一个结点的后继。
2.基本实现:
1)记录长度
2)判空、清空、移除元素并返回
3)增加元素,指定位置增加元素,获得首结点、尾结点元素。获得指定位置的元素
4)遍历
public class TowWayLinkList<T> implements Iterable<T> { //记录首结点 private Node head; //记录尾结点 private Node last; //记录链表长度 private int N; //节点类 private class Node{ //存储的数据 private T item; //结点 private Node pre;//指向前一个结点 private Node next;//指向后一个结点 public Node(T item, Node pre, Node next) { this.item = item; this.pre = pre; this.next = next; } } //初始化 public TowWayLinkList() { //初始化链表 this.head= new Node(null,null,null); this.last=null; this.N=0; } //将链表置为空 public void clear(){ this.head.next=null; this.last=null; this.N=0; } //判断当前链表是否为空 public boolean isEmpry(){ return N==0; } //获取链表的长度 public int length(){ return N; } //获取链表中的第一个元素 public T getFirst(){ if(isEmpry()){ return null; } return head.next.item; } //获取链表中的最后一个元素 public T getLast(){ if (isEmpry()){ return null; } return last.item; } //向链表中添加元素 public void insert(T t) { //如果链表为空 if(isEmpry()){ //创建新结点 Node newNode = new Node(t, head, null); last=newNode; head.next=last; }else { //当前尾结点 Node oldLast=last; //如果链表不为空,创建新结点 Node newLast = new Node(t, oldLast, null); //当前尾结点指向新结点 oldLast.next=newLast; //让新结点为尾结点 last=newLast; } //元素加一 N++; } //向指定位置添加元素 public void insert(int i,T t){ //找到i位置的上一个结点 Node n= head; for (int index=0;index<=i-1;index++){ n=n.next; } //i位置的结点 Node curr=n.next; //创建一个新结点 Node newNode=new Node(t,n,curr); //i位置的前一个结点指向新节点 n.next=newNode; //让新结点指向i newNode.next=curr; //个数加一 N++; } //获得指定位置的元素 public T get(int i){ Node n=head; for (int index=0;index<=i;index++){ n=n.next; } return n.item; } //删除指定位置元素,返回该元素 public T remove(int i){ Node n=head; //找到i的前一个结点 for (int index=0;index<=i-1;i++){ n=n.next; } //i位置的结点 Node curr=n.next; //i位置的后一个结点 Node h =curr.next; //i的前一个结点指向i位置的后一个结点 n.next=h; //i位置的后一个结点指向i的前一个结点 h.pre=n; N--; return curr.item; } //查找元素第一次出现的位置 public int indexOf(T t){ Node n =head; for (int index=0;n.next!=null;index++){ if (n.next.item.equals(t)){ return index; } } return -1; } /** * 双向链表表遍历 * 1)让类实现Iterable接口,重写iterator方法 * 2)在类内部提供一个内部类SIterator,实现iteator接口,重写hasNext和Next方法 */ @Override public Iterator<T> iterator() { return new SIterator(); } private class SIterator implements Iterator{ private Node n; public SIterator(){ this.n=head; } /** * 是否还有元素 * @return */ @Override public boolean hasNext() { return n.next!=null; } /** * 返回下一个元素 */ @Override public Object next() { n=n.next; return n.item; } } }
public class TowWayLinkList<T> implements Iterable<T> { //记录首结点 private Node head; //记录尾结点 private Node last; //记录链表长度 private int N; //节点类 private class Node{ //存储的数据 private T item; //结点 private Node pre;//指向前一个结点 private Node next;//指向后一个结点 public Node(T item, Node pre, Node next) { this.item = item; this.pre = pre; this.next = next; } } //初始化 public TowWayLinkList() { //初始化链表 this.head= new Node(null,null,null); this.last=null; this.N=0; } //将链表置为空 public void clear(){ this.head.next=null; this.last=null; this.N=0; } //判断当前链表是否为空 public boolean isEmpry(){ return N==0; } //获取链表的长度 public int length(){ return N; } //获取链表中的第一个元素 public T getFirst(){ if(isEmpry()){ return null; } return head.next.item; } //获取链表中的最后一个元素 public T getLast(){ if (isEmpry()){ return null; } return last.item; } //向链表中添加元素 public void insert(T t) { //如果链表为空 if(isEmpry()){ //创建新结点 Node newNode = new Node(t, head, null); last=newNode; head.next=last; }else { //当前尾结点 Node oldLast=last; //如果链表不为空,创建新结点 Node newLast = new Node(t, oldLast, null); //当前尾结点指向新结点 oldLast.next=newLast; //让新结点为尾结点 last=newLast; } //元素加一 N++; } //向指定位置添加元素 public void insert(int i,T t){ //找到i位置的上一个结点 Node n= head; for (int index=0;index<=i-1;index++){ n=n.next; } //i位置的结点 Node curr=n.next; //创建一个新结点 Node newNode=new Node(t,n,curr); //i位置的前一个结点指向新节点 n.next=newNode; //让新结点指向i newNode.next=curr; //个数加一 N++; } //获得指定位置的元素 public T get(int i){ Node n=head; for (int index=0;index<=i;index++){ n=n.next; } return n.item; } //删除指定位置元素,返回该元素 public T remove(int i){ Node n=head; //找到i的前一个结点 for (int index=0;index<=i-1;i++){ n=n.next; } //i位置的结点 Node curr=n.next; //i位置的后一个结点 Node h =curr.next; //i的前一个结点指向i位置的后一个结点 n.next=h; //i位置的后一个结点指向i的前一个结点 h.pre=n; N--; return curr.item; } //查找元素第一次出现的位置 public int indexOf(T t){ Node n =head; for (int index=0;n.next!=null;index++){ if (n.next.item.equals(t)){ return index; } } return -1; } /** * 双向链表表遍历 * 1)让类实现Iterable接口,重写iterator方法 * 2)在类内部提供一个内部类SIterator,实现iteator接口,重写hasNext和Next方法 */ @Override public Iterator<T> iterator() { return new SIterator(); } private class SIterator implements Iterator{ private Node n; public SIterator(){ this.n=head; } /** * 是否还有元素 * @return */ @Override public boolean hasNext() { return n.next!=null; } /** * 返回下一个元素 */ @Override public Object next() { n=n.next; return n.item; } } }