编程导航算法通关村第一关 | 双向链表的构造以及元素的插入和删除

双向链表

本双向链表的实现分别用first和last来表示头结点和尾结点,但此处的first和last即为第一个结点和最后一个结点本身,first和last的定义类似于一种指针的形式。没有对头结点和尾结点单独进行创建。

双向链表的构造

首先对双线链表类进行创建

public class DoublyLinkList {
    private DoubleNode first;
    private DoubleNode last;

    public DoublyLinkList() {
        first = null;
        last = first;
    }
}

然后创建内部节点类

class DoubleNode {
        public int data;    //数据域
        public DoubleNode next;    //指向下一个结点
        public DoubleNode prev;

        public DoubleNode(int data) {
            this.data = data;
        }

        //打印结点的数据域
        public void displayNode() {
            System.out.print("{" + data + "} ");
        }
    }

对于双向链表的结点,需要分别定义next域以及prev域来分别指向其前驱结点和后继结点。

元素插入

首先对于头插法和尾插法进行实现,代码如下:(其中isEmpty()方法是对first是否为空进行判断)

// 头部插入
    public void insertFirst(int data) {
        DoubleNode newNode = new DoubleNode(data);
        if (isEmpty()) {
            last = newNode;
        } else {
            first.prev = newNode;
        }
        newNode.next = first;
        first = newNode;
    }


    // 尾部插入
    public void insertLast(int data) {
        DoubleNode newNode = new DoubleNode(data);
        if (isEmpty()) {
            first = newNode;
        } else {
            last.next = newNode;
            newNode.prev = last;
        }
        last = newNode;
    }

当元素从指定key之后插入时,代码实现如下:

// 某个结点的后部插入
    public void insertAfter(int key, int data) {
        DoubleNode newNode = new DoubleNode(data);
        DoubleNode curr = first;
        while ((curr != null) && (curr.data != key)) {
            curr = curr.next;
        }
        // 判断当前结点是否为空
        if (curr == null) {
            // 1.首结点是否为空
            if (isEmpty()) {
                last = newNode;
                first = newNode;
            } else {
                // 2.找不到key值
                last.next = newNode;
                newNode.prev = last;
                last = newNode;
            }
        } else {
            // 当前结点不为空时,又有以下两种情况
            // 1.找到的key对应的结点在最后
            if (curr == last) {
                newNode.next = null;
                last = newNode;
            } else {
                // 2.在两个结点之间找到
                newNode.next = curr.next;
                curr.next.prev = newNode;
            }
            curr.next = newNode;
            newNode.prev = curr;
        }
    }

元素删除

删除首个元素和删除末尾元素的方法如下:(这里要注意,删首个元素时,如果只有一个元素,需要用last去指向null,反之则是用first指向。否则下面first.next会报空指针异常)

// 删除首个元素
    public DoubleNode deleteFirst() {
        DoubleNode temp = first;
        // 如果只有一个元素
        if (first.next == null) {
            // 将last指向null
            last = null;
        } else {
            // 如果由两个及以上的元素
            first.next.prev = null;
        }
        first = first.next;
        return temp;
    }

    // 删除尾部元素
    public DoubleNode deleteLast() {
        DoubleNode temp = last;
        if (first.next == null) {
            // 如果只有一个元素
            first = null;
        } else {
            // 如果有两个及两个以上的元素
            last.prev.next = null;
        }
        last = last.prev;
        return temp;
    }

对于从中间某处元素的删除,则需要改动两处元素指向,并且判断情况。其中如果curr为first或者last时,需要像上述方法一样进行是否为单元素的判断,这里直接引用了上面的方法,否则可能会有空指针异常。

public DoubleNode deleteAfter(int key) {
        DoubleNode curr = first;
        while ((curr != null) && (curr.data != key)) {
            curr = curr.next;
        }
        if (curr == null) {
            return null;
        } else {
            // 如果curr是第一个结点
            if (curr == first) {
                deleteFirst();
            } else if (curr == last) {
                // 如果curr是最后一个结点
                deleteLast();
            } else {
                curr.prev.next = curr.next;
                curr.next.prev = curr.prev;
            }
        }
        return curr;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值