双向链表MyLinkList

目录

一、定义方法

二、实现方法

1、打印链表

2、头插法

3、尾插法

4、链表长度

5、在任意位置插入

6、判断是否包含目标节点

7、删除key节点

8、删除所有为key的节点

9、清空链表

三、使用方法


实现一个双向链表,可以对链表进行方法的实现。

一、定义方法

列出链表要实现的方法,定义成一个接口,让MyLinkList来实现。

public interface IList {

        //打印

        void display();

        //头插法

        void addFist(int data);

        //尾插法

        void addLast(int data);

        //在任意位置插入

        void addIndex(int index,int data);

        //查找关键字key是否在单链表中

        boolean contains(int key);

        //删除第一个关键字为key的节点

        void remove(int key);

        //删除所有为key的节点

        void removeAllKey(int key);

        //单链表长度

        int size();

        //清空单链表

        void clear();

    }

二、实现方法

定义一个双向链表:

public class MyLinkList implements IList {

    static class ListNode {
​​​​​​​
        public int val;

        public ListNode next;

        public ListNode prev;


        public ListNode(int val) {

            this.val = val;

        }
    }

    public ListNode head;

    public ListNode last;

}

1、打印链表

  定义一个节点cur从头节点开始对链表进行遍历,打印链表的值。

 public void display() {

        ListNode cur=head;

        while (cur!=null){

            System.out.print(cur.val+" ");

            cur=cur.next;

        }

        System.out.println();

    }

2、头插法

     先定义出要插入的对象node,判断要插入的链表是否为空,为空中间让要插入的节点成为头节点,不为空就让插入的节点和头节点进行前后绑定,让新插入的节点成为新的头节点。

public void addFist(int data) {

        ListNode node=new ListNode(data);

        if (head==null){

            head=node;

        }else {

            node.next=head;

            head.prev=node;

            head=node;

        }

    }

3、尾插法

  先判断链表是否为空,为空直接让插入的节点成为新的头节点和尾节点,不为空新插入的节点和尾节点前后绑定,让新插入的节点成为新的尾节点。

  public void addLast(int data) {

        ListNode node=new ListNode(data);

        if (head==null) {

            head=node;

            last=node;

        }else {

            last.next=node;

            node.prev=last;

            last=node;

        }

    }

4、链表长度

    定义一个节点cur,从头节点往后遍历,用count来记录遍历节点的个数,返回count就是链表的长度。

 public int size() {

        ListNode cur=head;

        int count=0;

        while (cur!=null){

            count++;

            cur=cur.next;

        }

        return count;

    }

5、在任意位置插入

  先定义一个异常,如果插入的位置错误,就抛出这个异常。定义一个findIndex方法来查找要插入节点的位置cur,cur在要插入的节点node后面。再判断插入的位置是否在链表的最前和最后,使用头插法和尾插法。在链表内部插入,让新插入的节点和cur绑定,然后和原来在cur前面的节点进行绑定。

在任意位置插入是在任意位置的后面插入

class CheckIndex extends RuntimeException {

    public CheckIndex(String message) {

        super(message);

    }

}

    private ListNode findIndex(int index) {

        ListNode cur = head;

        while (index != 0) {

            cur = cur.next;

            index--;

        }

        return cur;

    }

    public void addIndex(int index, int data) {

        if (index < 0 || index > size()) {

            throw new CheckIndex("插入位置异常");

        }

        if (index == 0) {

            addFist(index);

        }

        if (index == size()) {

            addLast(index);

        }

        ListNode node = new ListNode(data);

        ListNode cur = findIndex(index);

        node.next = cur;

        cur.prev.next = node;

        node.prev = cur.prev;

        cur.prev = node;


    }

6、判断是否包含目标节点

  先判断链表是否为空,不为空就让cur从头节点往后进行遍历,找到目标节点就返回ture,没有找到就返回false。

 public boolean contains(int key) {

        if (head==null){

            System.out.println("链表为空");

        }else {

            ListNode cur=head;

            while (cur!=null) {

                if (cur.val == key) {

                    return true;

                }

                cur=cur.next;

            }

        }

        return false;

    }

7、删除key节点

       让cur从头节点往后进行遍历,找到要删除的节点,判断节点所在位置。在头节点,判断是否链表中只有头节点这一个节点,只有这一个节点就将last置为空,不只有这一个节点,就让让新的头节点的prev置为空。要删除的节点在链表中或者在链表的最后,让要删除的节点的前后节点进行绑定,如果是最后的节点,让last等于前一个节点。

 public void remove(int key) {

        ListNode cur=head;

        while (cur!=null){

            if (cur.val==key){   //有这个值

                if (cur==head){   //head等于这个值

                    head=head.next;

                    if (head==null){   //就head这一个节点

                        last=null;

                    }else {

                        head.prev=null;   //还有其他节点

                    }


                }else {

                    cur.prev.next=cur.next;

                    if (cur.next==null){ //last等于这个值

                        last=last.prev;


                    }else {

                        cur.next.prev=cur.prev; //除head和last等于这个值

                    }


                }

                return;

            }

            cur=cur.next;

        }

    }

8、删除所有为key的节点

  删除所有为key的节点,就是让cur继续向后进行遍历,找到目标节点进行删除。

 public void removeAllKey(int key) {

        ListNode cur = head;

        while (cur != null) {

            if (cur.val == key) {   //有这个值

                if (cur == head) {   //head等于这个值

                    head = head.next;

                    if (head == null) {   //就head这一个节点

                        last = null;
 
                    } else {

                        head.prev = null;   //还有其他节点

                    }


                } else {

                    cur.prev.next = cur.next;

                    if (cur.next == null) {   //last等于这个值

                        last = last.prev;


                    } else {

                        cur.next.prev = cur.prev;   //除head和last等于这个值

                    }


                }

            }

            cur=cur.next;

        }

    }

9、清空链表

       让cur从头节点往后进行遍历,将节点的next和prev都置为空,如果节点中存入的是引用数据类型,将节点的val也置为空

public void clear() {

        ListNode cur=head;

        while (cur!=null){

            ListNode tmp=cur.next;

            cur.prev=null;

            cur.next=null;

            cur=tmp;

        }

        head=null;

        last=null;

    }

三、使用方法

  定义一个Main类,来对方法进行使用。

public class Main {

    public static void main(String[] args) {

       MyLinkList myLinkList1=new MyLinkList();


       myLinkList1.addLast(1);
       myLinkList1.addLast(2);
       myLinkList1.addLast(3);
       myLinkList1.addLast(4);
       myLinkList1.addLast(1);
       myLinkList1.addFist(2);

       myLinkList1.display();



       myLinkList1.addIndex(3,5);   //插入是插入到输入位置的后面


        myLinkList1.display();



        System.out.println(myLinkList1.contains(2));


        System.out.println(myLinkList1.contains(6));


        myLinkList1.remove(2);


        myLinkList1.display();



        myLinkList1.removeAllKey(1);


        myLinkList1.display();



        myLinkList1.clear();


        myLinkList1.display();



    }

}

执行结果:

2 1 2 3 4 1 
2 1 2 5 3 4 1 
true
false
1 2 5 3 4 1 
2 5 3 4 
 


以上就是对双向链表进行简单的实现

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值