双向链表的增删改查Java

目录

创建链表

插入节点

查找

找索引index对应的节点

判断用户输入的索引是否合法:

修改

删除

输出语句

测试结果


创建链表

BothwayLinkList类相当于火车类存头节点,尾节点和链表的长度,Node类相当于火车的车厢,存放具体节点的值,和该节点的前驱和后继

public class BothwayLinkList {
    int size;
    Node head;
    Node tail; //尾节点
    class Node{
        int val;
        Node prev;//前驱
        Node next;//后继
        public Node(int val){this.val=val;}
        public Node(Node prev,int val,Node next){
            this.prev=prev;
            this.next=next;
            this.val=val;
        }
    }

插入节点

1.在头部插入:

 public void  firstIndex(int val){//头插
        Node node=new Node(null,val,head);
        if(head==null){
            tail=node;
        }else {
            head.prev=node;
        } head=node;
        size++;
    }

2.在尾部插入:

public void addLast(int val){//尾插
        Node node =new Node(tail,val,null);
        if (tail==null){

            head=node;
        }else {
            tail.next = node;
        }tail=node;
        size++;
    }

3.在中间位置插入:注意下标(index)是从0开始!

public void addIndex(int index,int val){//在下标为index位置插入值为val的节点
       if(index<0||index>size){
           System.out.println("illegal!!!");
           return;
       }else if(index==0){
           firstIndex(val);
       }
       else if (index==size){
           addLast(val);
       }
       else {
           Node front=find(index-1);//front是待插入节点的前驱
        Node node=new Node(front,val,front.next);
           front.next=node;
           front.next.prev=node;
           size++;

    }

    }

查找

下面两个方法是为后面的操作做准备,会被多次调用

找索引index对应的节点

private Node find(int index) {//找index对应的节点
        Node ret=null;
        if (index<size>>1){//从头开始找
            ret=head;
            for (int i = 0; i <index; i++) {
                ret=ret.next;
            }
        }else {//此时从后向前找
            ret=tail;
            for (int i = size-1; i > index; i--) {
                ret=ret.prev;
            }
        }return ret;
    }

判断用户输入的索引是否合法:

private boolean judgeIll(int index) {//判断合法性
        if (index<0||index>=size){return false;
        }
       return true;
    }

1.查找链表中是否含有某个值

 public boolean seekVal(int val){//查找值
        for (Node temp = head;temp !=null;temp=temp.next) {
            if (temp.val==val){
                return true;
            }
        }return false;
    }

2.查找某个节点对应的值为多少:调用上面的find()方法找到对应的节点

public int get(int inddex){//查索引对应的值
        if(judgeIll(inddex)==true){
            return find(inddex).val;//调用方法找到该节点
        }else {
            System.out.println("输入位置非法");
            return -1;
        }

    }

修改

public int changeVal(int index,int newval){//修改索引对应的值并返回原来的值
        if (judgeIll(index)){
            int oldVal=find(index).val;
            find(index).val=newval;
            return oldVal;
        }return -1;//输入不合法,返回-1
         }

删除

1.删除指定节点:这里采用分治思想,先处理节点的前半部分,再处理后半部分

private void unlink(Node node){//在链表中删除指定节点
        Node prev=node.prev;
        Node next=node.next;
        if (prev==null){//先处理前半部分
            head=next;
        }else{
            prev.next=next;
            node.prev=null;

        }
        if (next==null){//接着处理后半边
            tail=prev;
        }else {
            next.prev=prev;
            node.next=null;
        }size--;
}

2.删除索引位置的节点:

public void removeIndex(int index){
        if(judgeIll(index)){
            Node node=find(index);//找到该位置的节点
            unlink(node);
        }else {
            System.out.println("illegal!");
        }
}
public void removeFirst(){//删头
        removeIndex(0);
}
public void removeLast(){//删尾
        removeIndex(size-1);
}

3.删除某个值(只删除第一次出现的值):

public void removeOnce(int val){
        for(Node x=head;head!=null;x=x.next){
            if (x.val==val){
                Node next=x.next;
                unlink(x);//调用unlink方法删除x节点
                break;
            }
        }
}

4.删除某个值(对应的值全部删除):

public void removeValAll(int val){
    for (Node x=head;x!=null;) {
        if (x.val==val){
            Node next=x.next;//next是下一个要判断的节点
            unlink(x);
            x=next;
        }else {//继续向后走
            x=x.next;

        }
    }
}

输出语句

 public String toString(){
        String ret=" ";
        Node prev=head;
        //LinkLIST.NewNode prev=head;
        while (prev!=null){
            ret+= prev.val;
            ret+="-->";
            prev=prev.next;
        }
       ret+="NULL";
        return ret;
    }

测试结果

public class Test3 {//双链表的测试

    public static void main(String[] args) {
        BothwayLinkList b=new BothwayLinkList();
        b.firstIndex(7);
        b.firstIndex(8);
        System.out.println(b);
        b.addLast(5);
        b.addLast(1);
        System.out.println(b);//8>7>5>1
        b.addIndex(0,2);
        System.out.println(b);//2>8>7>5>1
        b.addIndex(6,9);
        System.out.println(b);//illegal
        b.addIndex(3,7);
        System.out.println(b);
        System.out.println(b.seekVal(2));
        System.out.println(b.seekVal(9));
        System.out.println(b.get(2));
        System.out.println(b.changeVal(2,10));
        b.removeIndex(2);
        System.out.println(b);
        b.removeOnce(8);
        System.out.println(b);
    }
}

输出结果为:

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值