数据结构——单链表的Java实现

前面我们讲了线性表的java实现。线性表的Java实现

它是有缺点的,最大的缺点在于插入和删除时需要移动大量元素,当表很长时,对性能的损耗严重。

今天来介绍表的链式存储结构——单链表。


单链表的存储结构

单链表:链表中的每一个节点由元素和对下一个节点的引用组成。

指针域 - 每一个节点包含指向下一个节点的指针

节点 - 节点由元素和指向下一个节点的指针组成。



链表在jdk中也有实现-LinkedList, 现在我们自己来实现一个LinkedList.

首先定义一个元素类,单链表我们需要一个表头header

    private Node header;

    private class Node {
        public Elem data;

        public Node next;
    }


单链表的插入

先来看单链表的插入,假设要插入的节点为s,要将s插入到p和q之间,只需要让s.next和p.next做一点改变即可。

s.next = p.next;
p.next = s;

这里注意顺序不能颠倒,如果先p.next = s,此时会使p.next被覆盖为s的地址了;再执行s.next = p.next,相当于s.next = s; 

就不符合我们需要插入的顺序了。所以这里一定要注意插入代码的顺序。

我们来看完整的插入代码:

public void insert(Elem e, int index) {
        if (header == null) {
            LogUtil.d(TAG, "LinkedList header is empty, can not insert");
        } else {
            Node p = new Node();
            p.data = e;
            int i = 0;
            Node temp = header;
            while (i < index && temp != null) {
                temp = temp.next;
                i++;
            }
            if (temp == null) {
                LogUtil.d(TAG, "Insert index out of bounds");
                return;
            }

            p.next = temp.next;
            temp.next = p;
        }
    }

分析:

1.从头节点开始遍历链表,直到找到要插入的位置;

2.如果找到插入的位置,执行上述的插入操作;

3.如果没有找到插入的位置,则说明数组越界,返回。


单链表的删除

再来看单链表的删除,删除操作相对插入要简单直观一些,假设要删除的节点为p,只需要:

p.next = p.next.next;

这个直接从图上看很直观,就不做解释了。看完整代码:

public void delete(int index) {
        if (header == null) {
            LogUtil.d(TAG, "LinkedList header is empty, can not delete");
        } else {
            if (index == 0) {
                deleteAtFirst();
            } else {
                int i = 0;
                Node temp = header;
                Node prev = header;
                while (i < index && temp != null) {
                    prev = temp;
                    temp = temp.next;
                    i++;
                }
                if (temp == null) {
                    LogUtil.d(TAG, "Delete index out of bounds");
                    return;
                }
                Node deleteNode = prev.next;
                prev.next = prev.next.next;
                deleteNode = null;
            }
        }
    }

删除的思路和插入类似,先遍历找到要删除的节点,然后执行删除操作;

需要注意的是,如果删除的是头节点,需要对header做特殊的操作。


好了,插入和删除讲完了,至于get操作,其实已经包含在插入和删除的代码中了,直接遍历找到对应位置的元素即可。


文末推荐个人开发的app,Google Play : 数据结构与算法教程 (需要科学上网)

提供了丰富的动画演示、模拟场景来帮助你更好的理解抽象的数据结构和复杂的算法。(文中的动图都是从app中截取的片段)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值