【 双向链表】 实现一个双向链表,主要功能有头插,头删,尾插,尾删,按下标插入,按下标删除,按下标查找,按元素查找,按元素删除等等

学习目标:

目标:熟练运用Java所学知识


学习内容:

本文内容:使用Java实现:自己实现一个链表,主要功能有,头插,头删,尾插,尾删,按下标插入,按下标删除等等


具体实现:

  • 首先创建一个节点
class ListNode {
    int val;
    ListNode next;//指向下一个节点
    ListNode prev;//指向前一个结点
    public ListNode(int val){
        this.val=val;
    }
}
  • 创建头尾结点和记录长度的变量
   public ListNode head=null;//头结点
   private ListNode tail=null;//尾节点
   private int length=0;//记录链表长度
  • 按位置获取结点
//按位置获取结点
public ListNode getNode(int index){
    ListNode cur=head;
    //当位置输入有误
    if(index<0||index>=length){
        return null;
    }
    //通过for循环遍历到当前结点
    for(int i=0;i<index;i++){
        cur=cur.next;
    }
    return cur;
}
  • 头插操作
public void addFirst(int val){
    ListNode newNode=new ListNode(val);//为val创建新节点
    //链表为空时,将新节点赋给头尾结点并返回
    if(head==null){
        head=newNode;
        tail=newNode;
        length++;
        return;
    }
    //链表不为空时。头插新节点
    newNode.next=head;
    head.prev=newNode;
    head=newNode;
    length++;
}
  • 尾插
//尾插
public void addLast(int val){
    ListNode newNode=new ListNode(val);//为val创建新节点
    //链表为空时,将新节点赋给头尾结点并返回
    if(tail==null){
        head=newNode;
        tail=newNode;
        length++;
        return;
    }
    //链表不为空时,尾插新节点
    tail.next=newNode;
    newNode.prev=tail;
    tail=newNode;//更新尾结点
}
  • 按指定位置插入
//指定位置插入
public void add(int index,int val){
    ListNode newNode=new ListNode(val);//为val创建新节点
    //当下标输入错误时
    if(index<0||index>length){
        System.out.print("位置输入错误");
        return;
    }
    //下标等于0,直接调用头插操作
    if(index==0){
        addFirst(val);
        return;
    }
    //下标等于长度,调用尾插操作
    if(index==length){
        addLast(val);
        return;
    }

    ListNode curNode=getNode(index);//调用按位置获取结点方法获取index下标位置的结点
    ListNode preNode=curNode.prev;//要插入位置的前一个结点
    //插入新节点
    preNode.next=newNode;
    newNode.prev=preNode;

    newNode.next=curNode;
    curNode.prev=newNode;

    length++;
}
  • 头删
//头删
public void removeFirst(){
    //链表为空
    if(head==null){
        return;
    }
    //链表只有一个节点
    if(head.next==null){
        head=null;
        tail=null;
        length=0;
        return;
    }
    head.next.prev=null;//删除头结点
    head=head.next;//更新头结点
    length--;
}
  • 尾删
//尾删
public void removeLast(){
    //链表为空
    if(head==null){
        return;
    }
    //链表只有一个节点
    if(head.next==null){
        head=null;
        tail=null;
        length=0;
        return;
    }
    tail.prev.next=null;//删除尾结点
    tail=tail.prev;//更新尾结点
    length--;
}
  • 按照下标删除
//按照下标删除
public void removeByIndex(int index){
    //输入的下标不合法时
    if(index<0||index>=length){
        return;
    }
    //下标为0,调用头删操作
    if(index==0){
        removeFirst();
        return;
    }
    //下标为尾结点,调用尾删操作
    if(index==length-1){
        removeLast();
        return;
    }
    
    ListNode cur=getNode(index);//调用按位置获取结点方法得到下标的结点
    //删除当前结点
    cur.prev.next=cur.next;
    cur.next.prev=cur.prev;
    length--;
}
  • 按给定值删除
//按给定值值删除
public void removeByVal(int value){
    int index=getIndex(value);//获取当前值对应的下标
    //下标不合法时
    if(index==-1){
        return;
    }
    removeByIndex(index);//调用按照位置删除的操作
}
  • 按给定值获取对应下标
//按值获取下标
public int getIndex(int value){
    ListNode cur=head;
    //循环遍历,找对应值
    for(int i=0;i<length;i++){
        //当找到对应值的,返回对应下标
        if(cur.val==value){
            return i;
        }
            cur=cur.next;
    }
    return -1;
}
  • get,set方法
public int get(int index){
    if(index<0||index>=length){
        return -1;
    }
    return getNode(index).val;
}
public void set(int index,int value){
    if(index<0||index>=length){
        return;
    }
    getNode(index).val=value;
}

代码汇总:

public class MyLinkedList
    {
        @Override
        public String toString() {
            return "MyLinkedList{" +
                    "head=" + head.val +
                    ", tail=" + tail.val +
                    '}';
        }
        public static void printList(ListNode head) {
            ListNode cur = head;
            while (cur != null) {
                System.out.println(cur.val);
                cur = cur.next;
            }
        }
        public ListNode head=null;//头结点
        private ListNode tail=null;//尾节点
        private int length=0;//记录链表长度
        //头插
        public void addFirst(int val){
            ListNode newNode=new ListNode(val);//为val创建新节点
            //链表为空时,将新节点赋给头尾结点并返回
            if(head==null){
                head=newNode;
                tail=newNode;
                length++;
                return;
            }
            //链表不为空时。头插新节点
            newNode.next=head;
            head.prev=newNode;
            head=newNode;
            length++;
        }
        //尾插
        public void addLast(int val){
            ListNode newNode=new ListNode(val);//为val创建新节点
            //链表为空时,将新节点赋给头尾结点并返回
            if(tail==null){
                head=newNode;
                tail=newNode;
                length++;
                return;
            }
            //链表不为空时,尾插新节点
            tail.next=newNode;
            newNode.prev=tail;
            tail=newNode;//更新尾结点
        }
        //指定位置插入
        public void add(int index,int val){
            ListNode newNode=new ListNode(val);//为val创建新节点
            //当下标输入错误时
            if(index<0||index>length){
                System.out.print("位置输入错误");
                return;
            }
            //下标等于0,直接调用头插操作
            if(index==0){
                addFirst(val);
                return;
            }
            //下标等于长度,调用尾插操作
            if(index==length){
                addLast(val);
                return;
            }

            ListNode curNode=getNode(index);//调用按位置获取结点方法获取index下标位置的结点
            ListNode preNode=curNode.prev;//要插入位置的前一个结点
            //插入新节点
            preNode.next=newNode;
            newNode.prev=preNode;

            newNode.next=curNode;
            curNode.prev=newNode;

            length++;
        }
        //头删
        public void removeFirst(){
            //链表为空
            if(head==null){
                return;
            }
            //链表只有一个节点
            if(head.next==null){
                head=null;
                tail=null;
                length=0;
                return;
            }
            head.next.prev=null;//删除头结点
            head=head.next;//更新头结点
            length--;
        }
        //尾删
        public void removeLast(){
            //链表为空
            if(head==null){
                return;
            }
            //链表只有一个节点
            if(head.next==null){
                head=null;
                tail=null;
                length=0;
                return;
            }
            tail.prev.next=null;//删除尾结点
            tail=tail.prev;//更新尾结点
            length--;
        }
        public int size(){
            return length;
        }
        //按照下标删除
        public void removeByIndex(int index){
            //输入的下标不合法时
            if(index<0||index>=length){
                return;
            }
            //下标为0,调用头删操作
            if(index==0){
                removeFirst();
                return;
            }
            //下标为尾结点,调用尾删操作
            if(index==length-1){
                removeLast();
                return;
            }

            ListNode cur=getNode(index);//调用按位置获取结点方法得到下标的结点
            //删除当前结点
            cur.prev.next=cur.next;
            cur.next.prev=cur.prev;
            length--;
        }
        //按给定值值删除
        public void removeByVal(int value){
            int index=getIndex(value);//获取当前值对应的下标
            //下标不合法时
            if(index==-1){
                return;
            }
            removeByIndex(index);//调用按照位置删除的操作
        }

        //按值获取下标
        public int getIndex(int value){
            ListNode cur=head;
            //循环遍历,找对应值
            for(int i=0;i<length;i++){
                //当找到对应值的,返回对应下标
                if(cur.val==value){
                    return i;
                }
                    cur=cur.next;
            }
            return -1;
        }
        //按位置获取结点
        public ListNode getNode(int index){
            ListNode cur=head;
            //当位置输入有误
            if(index<0||index>=length){
                return null;
            }
            //通过for循环遍历到当前结点
            for(int i=0;i<index;i++){
                cur=cur.next;
            }
            return cur;
        }
        public int get(int index){
            if(index<0||index>=length){
                return -1;
            }
            return getNode(index).val;
        }
        public void set(int index,int value){
            if(index<0||index>=length){
                return;
            }
            getNode(index).val=value;
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值