双向链表 理解自我删除

        前面的单向链表练习发现:单向链表只能一个方向查找,并且删除元素时需要借助临时节点来存储数据链

        通过在节点类中加入一个 pre 指针指向前一个元素的方式就可以改变上面的劣势,实现自我删除

双向链表节点类

//双向链表节点
class DNode<T> {
    private int no; // 序号
    private T data; // data 域
    private DNode<T> pre;  // pre 域
    private DNode<T> next; // next 域

    //是否有下个元素
    public boolean hasNext() {
        return next != null;
    }

    @Override
    public String toString() {
        return "DNode{" +
                "no=" + no +
                ", data=" + data +
                ", name='" + name + '\'' +
                '}';
    }

    private String name; //辅助名
    public DNode(DNode<T> dNode) {
        this.data = dNode.getData();
        this.no = dNode.getNo();
        this.name = dNode.getName();
    }


    public DNode(T data, int no, String name) {
        this.data = data;
        this.no = no;
        this.name = name;
    }

    //getter、setter
}

 链表类

class DLinkedList<T> {
    private final DNode<T> head =
            new DNode<>(null, -1, null);    //首节点
    private DNode<T> rear;  //尾节点
    private DNode<T> temp;  //临时节点

    //打印
    public void list() {
        if (!head.hasNext()) {
            System.out.println("链表空");
            return;
        }
        temp = head.getNext();
        while (temp != null) {
            System.out.println(temp);
            temp = temp.getNext();
        }
    }
    //反打
    public void revList(){
        if (rear==null){
            System.out.println("链表空");
            return;
        }
        while (rear!=null&&rear!=head){
            System.out.println(rear);
            rear = rear.getPre();
        }
    }
}

    //增
    public void add(T data, int no, String name) {
        DNode<T> node = new DNode<>(data, no, name);
        //空链表直接加
        if (!head.hasNext()) {
            head.setNext(node);
            rear = node;
            return;
        }
        //否则在尾部加 node 然后 rear 指向 node
        rear.setNext(node);
        node.setPre(rear);
        rear = node;
    }
    //按序增
    public void addByNo(T data, int no, String name){
        DNode<T> node = new DNode<>(data, no, name);
        //空链表直接加
        if (!head.hasNext()) {
            head.setNext(node);
            rear = node;
            return;
        }
        //找到 no 位置
        DNode<T> temp = head.getNext();
        while (temp.getNo()<no){
            if (temp.getNo()==no){
                System.out.println("重复的 no: " + no);
                return;
            }
            temp = temp.getNext();
        }
        node.setPre(temp.getPre());
        node.setNext(temp);
        temp.getPre().setNext(node);
        temp.setPre(node);
    }

    //删
    public T popByNo(int no) {
        if (!head.hasNext()) {
            System.out.println("链表空");
            return null;
        }
        T r = null; //存放弹出删除节点的数据 data 的辅助变量
        temp = head.getNext();
        while (temp != null) {
            if (temp.getNo() == no) {   //找到后自我删除
                temp.getNext().setPre(temp.getPre());
                temp.getPre().setNext(temp.getNext());
                r = temp.getData();
                break;
            }
            temp = temp.getNext();
        }
        return r;
    }

    //改
    public void update(T data, int no, String name) {
        if (!head.hasNext()) {
            System.out.println("链表空");
            return;
        }
        temp = head.getNext();
        while (temp != null) {
            if (temp.getNo() == no) {
                temp.setData(data);
                temp.setName(name);
                break;
            }
            temp = temp.getNext();
        }
    }

    //查
    public DNode<T> getByNo(int no) {
        if (!head.hasNext()) {
            System.out.println("链表空");
            return null;
        }
        temp = head.getNext();
        while (temp != null) {
            if (temp.getNo() == no) {
                return new DNode<>(temp);
            }
            temp = temp.getNext();
        }
        return null;
    }

测试主方法

    public static void main(String[] args) {
        DLinkedList<LocalDateTime> list = new DLinkedList<>();
        list.add(LocalDateTime.now(), 1, "孙悟空");
        list.add(LocalDateTime.now(), 3, "唐僧");
        list.add(LocalDateTime.now(), 5, "猪八戒");
        list.add(LocalDateTime.now(), 9, "屠夫");
        System.out.println("----------list----------");
        list.list();
        System.out.println("----------remove----------");
        System.out.println("pop: " + list.popByNo(3));
        list.list();
        System.out.println("----------get----------");
        System.out.println("get: " + list.getByNo(5));
        System.out.println("----------insert----------");
        list.addByNo(LocalDateTime.now(),3,"不古井");
        list.list();
        System.out.println("----------revList----------");
        list.revList();
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值