数据结构-线性表之单链表(Java实现)

理解

点击这里查看大图
这里写图片描述
每一个圆代表一个节点,里面存放了相应的数据,每个节点连接着另一个节点,从而连成一条线。如果要做个类比,有点像行走在沙漠中的骆驼队:
点击这里查看大图
这里写图片描述
骆驼——节点
货物——数据(好吧,图中的骆驼没有背货物)
绳子——用来连接下一个节点

插入数据

1. 插入到末尾

点击这里查看大图
这里写图片描述
很简单,只需将链表末尾的节点指向新的节点。
类比骆驼队:如果新骆驼要加入到队伍的末尾,只需用一根绳子,将新骆驼绑到最后一个骆驼上就可以了。

2.插到头部

点击这里查看大图
这里写图片描述
也很简单,只需将新节点与链表的头节点建立连接。
类比骆驼队:如果新骆驼要加入到队伍的开头,只需将队伍中的第一个骆驼绑到新骆驼上就可以了。

3. 一般情况

点击这里查看大图
这里写图片描述

一般性操作稍微复杂一点:

1. 节点2与节点3断开连接
2. 节点2与新节点建立连接
3. 新节点与节点3建立连接

类比骆驼队:

1. 松开两个骆驼之间的绳子
2. 将新骆驼绑到前一个骆驼上
3. 将后一个骆驼绑到新骆驼上

移除数据

1. 移除开头

点击这里查看大图
这里写图片描述
很简单,只需将头节点与后面一个节点断开连接,这样,链表就是以后一个节点为头结点了。
类比骆驼队:要拿掉队伍开头的骆驼,只需该骆驼与后面队伍连接的绳子拿掉就可以了。

2. 移除末尾

点击这里查看大图
这里写图片描述
也很简单,只需将末尾的节点与前一个节点断开连接就可以了。这样,链表就是以之前链表末尾节点的前一个节点为末尾节点的链表了(反应到图中,就是以节点4位末尾节点的链表)
类比骆驼队,要拿掉队伍末尾的骆驼,只需将该骆驼与前面队伍连接的绳子拿掉就可以了。

3.一般情况

点击这里查看大图
这里写图片描述
一般情况的操作稍微复杂一些:

1. 节点2与节点3断开连接
2. 节点3与节点4断开连接
3. 节点2与节点4建立连接

类比骆驼队

1. 前一个骆驼与该骆驼之间的绳子拿掉
2. 该骆驼与后一个骆驼之间的绳子拿掉
3. 前一个骆驼与后一个骆驼之间用绳子拴起来

Java代码实现及演示

实现代码

public class MySingleList {
    //头结点
    private Node first;
    //末尾节点
    private Node last;
    //大小
    private int size = 0;

    //插入
    public void insert(int i, String s) {
        if (i < -1) {
            throw new IllegalArgumentException("i不能小于0");
        }
        if (i > size) {
            throw new IllegalArgumentException("i不能大于链表的长度");
        }
        Node node = new Node(s, null);
        //第一次插入数据
        if (first == null) {
            first = node;
            last = node;
            size++;
            look();
            return;
        }
        //插入到链表的末尾
        if (i == size) {
            last.next = node;
            last = node;
            size++;
            look();
            return;
        }
        //插入头
        if (i == 0) {
            node.next = first;
            first = node;
            size++;
            look();
            return;
        }
        //一般情况
        //找出相应的节点
        Node preNode = selectNode(i - 1);
        Node nextNode = preNode.next;
        preNode.next = node;
        node.next = nextNode;
        size++;
        look();
    }

    //移除
    public void remove(int index) {
        if (index < -1) {
            throw new IllegalArgumentException("index不能小于0");
        }
        if (index > size - 1) {
            throw new IllegalArgumentException("index不能大于链表的长度-1");
        }
        //1.移除头部
        if (index == 0) {
            Node oldFirst = first;
            first = first.next;
            oldFirst.s = null;
            oldFirst.next = null;
            oldFirst = null;
            size--;
            look();
            return;
        }

        //2.移除尾部
        if (index == size - 1) {
            Node oldLast = last;
            Node newLast = selectNode(size - 2);
            newLast.next = null;
            last = newLast;

            oldLast.s = null;
            oldLast = null;
            size--;
            look();
            return;
        }

        //3.一般情况下的处理
        Node preNode = selectNode(index - 1);
        Node node = preNode.next;
        Node nextNode = node.next;

        preNode.next = nextNode;
        node.next = null;
        node.s = null;
        node = null;
        size--;
        look();
    }

    public void clear() {
        //链表如果为空,不做处理
        if (first == null)
            return;
        Node p = first;
        Node q;
        while (p != null) {
            q = p.next;
            p.s = null;
            p.next = null;
            p = q;
        }
        first = null;
        last = null;
        size = 0;
        System.out.println("数据清空");
        look();


    }

    //找出指定的节点
    private Node selectNode(int i) {
        if (i < -1) {
            throw new IllegalArgumentException("i不能小于0");
        }
        if (i > size - 1) {
            throw new IllegalArgumentException("i不能大于链表的长度-1");
        }
        //i为0时的处理
        if (i == 0)
            return first;
        //i为size-1时的处理
        if (i == size - 1)
            return last;
        //处理头结点和末尾节点可以直接获取,其余的节点需要遍历才能获取到
        int index = 0;
        Node node = first;
        while (node != null && index < i) {
            index++;
            node = node.next;
        }
        return node;
    }


    //节点类
    class Node {
        public String s;
        public Node next;

        public Node(String s, Node next) {
            this.s = s;
            this.next = next;
        }
    }

    //用来查看链表中的数据
    private void look() {
        Node node = first;
        System.out.println("");
        while (node != null) {
            System.out.print(node.s + " ");
            node = node.next;
        }
    }

    public int getSize() {
        return size;
    }
}

插入操作演示

public class Main {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.insert(0,"1");
        list.insert(1,"2");
        list.insert(0,"3");
        list.insert(0,"4");
        list.insert(0,"5");
        list.insert(3,"6");
        list.insert(5,"7");
        list.insert(6,"8");
        list.insert(7,"9");
    }
}

结果

1 
1 2 
3 1 2 
4 3 1 2 
5 4 3 1 2 
5 4 3 6 1 2 
5 4 3 6 1 7 2 
5 4 3 6 1 7 8 2 
5 4 3 6 1 7 8 9 2 

移除及清空代码演示

public class Main {
    public static void main(String[] args) {
        MySingleList list = new MySingleList();
        list.insert(0,"1");
        list.insert(1,"2");
        list.insert(2,"3");
        list.insert(3,"4");
        list.insert(4,"5");
        list.insert(5,"6");

        list.remove(5);
        list.remove(0);
        list.remove(1);

        list.clear();
    }
}

结果

1 
1 2 
1 2 3 
1 2 3 4 
1 2 3 4 5 
1 2 3 4 5 6 
1 2 3 4 5 
2 3 4 5 
2 4 5 数据清空

结语

Java中LinkedList已经对这些操作进行了封装,我们可以直接使用

点击这里查看LinkedList源码的相关理解

转载请标明出处:http://blog.csdn.net/qq_26411333/article/details/51813833

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值