用非指针的方式来理解单向链表(用json数据的方式来理解java单向链表)

因为java里面是没有太多指针的概念,所以在学到数据结构的单向链表的时候容易搞糊涂

所以我用自己的理解方式来展示一下链表,就是常用的json数据格式

下面是代码:

  • 单向链表的节点类
/**
 * 节点类
 */
class DataNode {

    public String data; //存放节点数据 这里为了方便是String类型,实际的链表应该是泛型或者Object类型
    public DataNode next; // 存放下一个节点

    public DataNode(String data) {
        this.data = data;
    }

    /**
     * 重写toString 方便用json的格式打印出来
     */
    @Override
    public String toString() {
        return "{" +
                "\"data\":\"" + data + "\","+
                "\"next\":" + next +
                "}";
    }
}
  • 链表类
class SingleLinkedList {

    private final DataNode header; // 头部节点

    public SingleLinkedList(){
        this.header = new DataNode("链表头部");
    }

    public void add(String data) {
        // 1.找到链表最后一个节点对象 保存到变量 tempNode
        DataNode tempNode = header;
        while (tempNode.next != null) {
            tempNode = tempNode.next;
        }
        // 2.将新生成的节点指向链表最后的一个节点
        tempNode.next = new DataNode(data);
    }

    public int size() {
        int tempIndex = 0;
        DataNode tempNode = header;
        while (tempNode.next != null) {
            tempNode = tempNode.next;
            tempIndex ++;
        }
        return tempIndex;
    }

    /**
     * 移除指定位置的数据
     */
    public String get(int index) {
        // 1.找到位置为 i 的节点对象 保存到变量 tempNode
        DataNode tempNode = header.next;
        int tempIndex = 0;
        while (true) {
            if (tempNode == null) {
                throw new RuntimeException("访问不到的下标:"+ index);
            } else if (tempIndex == index){
                break;
            }
            tempNode = tempNode.next;
            tempIndex ++ ;
        }
        return tempNode.data;
    }

    /**
     * 移除指定数据,只移除第一个
     */
    public void remove(String data) {
        // 1.找到数据为 data 的节点对象 保存到变量 tempNode
        DataNode tempBeforeNode = header;
        DataNode tempNode;
        while (true) {
            tempNode = tempBeforeNode.next;
            if (tempNode == null) {
                throw new RuntimeException("在链表中找不到数据:"+ data);
            } else if (tempNode.data.equals(data)){
                break;
            }
            tempBeforeNode = tempBeforeNode.next;
        }
        // 2.将 tempNode 后面的节点指向 tempUpNode
        tempBeforeNode.next = tempNode.next;
    }

    /**
     * 移除指定位置的数据
     */
    public void remove(int index) {
        // 1.找到位置为 i 的节点对象 保存到变量 tempNode
        DataNode tempBeforeNode = header;
        DataNode tempNode;
        int tempIndex = 0;
        while (true) {
            tempNode = tempBeforeNode.next;
            if (tempNode == null) {
                throw new RuntimeException("访问不到的下标:"+ index);
            } else if (tempIndex == index){
                break;
            }
            tempBeforeNode = tempBeforeNode.next;
            tempIndex ++ ;
        }
        // 2.将 tempNode 后面的节点指向 tempUpNode
        tempBeforeNode.next = tempNode.next;
    }



    public String toString() {
        if (header.next == null) {
            return "{}";
        } else {
            return header.next.toString();
        }
    }

}
  • 测试类
public class SingleLinkedListDemo {

    public static void main(String[] args) {

        SingleLinkedList singleLinkedList = new SingleLinkedList();
        System.out.println("打印出空链表: " + singleLinkedList);
        singleLinkedList.add("大哥刘备");
        singleLinkedList.add("二哥曹操");
        singleLinkedList.add("三哥关羽");
        singleLinkedList.add("四弟张飞");
        System.out.println("添加数据后打印出链表: " + singleLinkedList);
        System.out.println("链表大小: " + singleLinkedList.size());
        System.out.println("链表第一个数据: " + singleLinkedList.get(0));
        singleLinkedList.remove(0);
        System.out.println("移除第一个数据后打印出链表: " + singleLinkedList);
        singleLinkedList.remove("四弟张飞");
        System.out.println("移除第'四弟张飞'后打印出链表: " + singleLinkedList);

    }

}

测试结果

打印出空链表: {}
添加数据后打印出链表: {"data":"大哥刘备","next":{"data":"二哥曹操","next":{"data":"三哥关羽","next":{"data":"四弟张飞","next":null}}}}
链表大小: 4
链表第一个数据: 大哥刘备
移除第一个数据后打印出链表: {"data":"二哥曹操","next":{"data":"三哥关羽","next":{"data":"四弟张飞","next":null}}}
移除第'四弟张飞'后打印出链表: {"data":"二哥曹操","next":{"data":"三哥关羽","next":null}}
  • 总结
    先用json格式化添加完数据
    用非指针的方式来理解单向链表(用json数据的方式来理解java单向链表)

对这个是不是一眼就看懂了,其实上一个节点和下一个节点可以看成父子关系,对照着这个格式化后的数据在脑子里过一遍下面的操作:
1. 获取链表的第一个数据
2. 移除链表的第一个数据
3. 移除'四弟张飞'

上一篇:Single linked list by cursor


下一篇:python设计模式(十九):备忘录模式