双向链表

一、双向链表

      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;
        }
    }
}

 

       

posted @ 2020-03-25 15:04  撑起一片阳光  阅读(434)  评论(0编辑  收藏  举报