数据结构之简单链表

作力扣 的算法题 忽然想到这个数据结构,以为有必要记录下来java

1. 定义一个Link类和一个Node类,其中Node类为Link类的内部类(避免了反复的getter和setter方法)
Link类的目的是进行节点建立
Node类的目的是进行数据和节点连接,而且Node只能为Link调用,须要定义为private
再定义一个Factory类,用来给客户端调用,返回的是一个Link类的实例node

2. Node类中须要包含有如下属性:
    (1) Object data : 用于存放数据
    (2) Node next : 用户存放指向下一个节点的数据
构造函数就是给data赋值
3. 增长1个追加函数,往链表中添加元素
    (1) 明确的是,追加数据要在Link类中完成
    (2) 须要先在Link类中声明root根节点
    (3) 若是没有传入数据,那么就直接返回,不作操做
    (4) 对于存放的数据,那么就要新建一个节点,新建一个节点对象,而后把这个节点对象交给Node类去处理
    (5) 第4步中,存放节点数据应该从root开始,若是root为空,那么存放的数据就是root,只要把新建节点赋值给root便可
        若是不是,那么就要把新建节点交由Node类处理,从root节点开始
    (6) Node类接收Link类传过来的newNode对象,作如下处理:
        判断root的next是否为空值,如果,则把newnode赋值给root.next
        若不为空,那么递归,下个是root.next.next
以上完成增长一个数据,并处理节点关系
测试程序为:
//
public class TestLinkDemo {
    public static void main(String[] args) {
        Link all = Factory.getInstance();
        all.add("AAA");
        all.add("BBB");
        all.add("CCC");
    }
}
//
4. 增长一个函数,获取链表中的数据个数
    (1) 在Link类中定义属性,统计个数,count
    (2) 定义方法,获取count,就是返回数据个数
    (3) 定义isEmpty()方法,判断链表是否为空
5. 增长一个函数,能够把链表转换成对象数组
    (1) 链表就是一个动态数组,返回类型为Object[] data,每一个数据的取得有前后顺序,所以须要定义一个游标
    (2) Link类中,首先须要判断,链表长度是否为零,若是是零,就返回空值,若是不是0,则须要遍历整个链表,
        游标为0,从root节点开始调用Node中取出数据的函数(新定义)
    (3) Node类中须要获取每一个节点的数据,并填写到数组中,若是判断下个节点还有数据,那么就要继续递归
6. 增长一个查询数据的方法
    (1) 须要equals方法支持
    (2) Node中追加一个方法,用于查找指定元素,并且必须从root节点开始日后找
    (3) Link中追加一个方法,用于判断必须输入查找内容,以及链表不为空,若正常,就调用Node中的方法,从root开始
    
7. 根据索引取得数据
    (1) 在Node类里面增长一个索引查找的方法,根据游标查找
    (2) 在Link类中增长一个索引查找方法,目的是保证链表有数据,同时初始化游标,查找的时候从root节点日后找算法

8. 修改指定索引的数据
    (1) 首先在Link类中定义一个方法,传入2个参数,第一个为索引值,第二个是要修改为的目标对象值
        考虑问题,若是索引超过了链表长度,那么就不修改,结束调用
        不然就先设定游标,而后从root节点开始调用Node中真正修改数据的函数
    (2) Node类中定义的方法,首先判断当前游标是否为指定游标,如果,则修改数据
        若不是,判断当前是否是最后一个节点,若是节点不为空,那么继续日后查找节点,递归调用数组

9. 删除数据
    (1) 全部的前提是存在该数据,全部首先由上面定义的查找方法进行查找
        若是删除的是根节点,更换root的操做只须要在Link类中完成便可
        若是不是,那么要把根节点的下一个节点交给Node类中的删除方法进行
    (2) Node类中判断当前对象的数据是不是要删除的数据,若是是的话,就把这个对象的上一个next指向下一个next数据结构

        若是不是,则继续递归删除函数

 

更新一下查找方法,原课程写的有问题测试

//根据索引取得数据
    public Object getNode(int searchIndex) {
      if (Link.this.index++ == searchIndex) {
        return this.data;
      } else {
        return this.next.getNode(searchIndex);
      }
    }
class Link {
    private Node root; //根节点,增长数据函数添加
    private int count; //统计元素个数
    private Object[] retData; //返回对象数组
    private int index = 0; //操做游标
    // 定义Node内部类,表示Node只为Link类服务
    private class Node { //负责 保存数据,节点关系配置
        private Object data;
        private Node next;
        public Node(Object data) {
            this.data = data;
        }
        //增长数据
        public void addNode(Node newNode) {
        if (this.next == null) {
            this.next = newNode;
        } else {
            this.next.addNode(newNode);
        }
        }
        //转换成对象数组
        public void toArrayNode() {
            Link.this.retData[Link.this.index ++] = this.data;//先把root节点的数据取出,而后游标加一
            if (this.next != null){ //若是下个节点还有数据,则递归获取
                this.next.toArrayNode();
            }
        }
        //查找数据
        public boolean containsNode(Object search) {
            if (search.equals(this.data)) {
                return true; //找到数据
            } else {
                if (this.next != null) { //还有后续节点
                    return this.next.containsNode(search);//递归查找
                } else {
                    return false;
                }
            }
        }
        //根据索引取得数据
        public Object getNode(int searchIndex) {
            if (Link.this.index ++ == searchIndex) {
                return this.data;
            } else {
                this.next.getNode(searchIndex);
            }
            return null;
        }
        //修改指定索引的数据
        public void setNode(int searchIndex, Object newData) {
            if (Link.this.index ++ == searchIndex) {
                this.data = newData;
            } else {
                if (this.next != null) {
                    this.next.setNode(searchIndex,newData);
                }
            }
        }
        //删除元素
        public void removeDataNode(Node previous, Object data) {
            if (this.data.equals(data)) {
                previous.next = this.next; //中间是this,若是this的data是所要删除的data,那么把this以前的一个node指向this以后的一个node
            } else {
                this.next.removeDataNode(this, data);
            }
        }
    }
    // ---------如下是Link类定义-----------
    //增长元素
    public void add(Object data) {
        if ( data == null ) {//不容许存放空值数据
            return;
        }
        Node newNode = new Node(data); //建立一个新的节点
        if (this.root == null) {
            this.root = newNode;
        } else {
            this.root.addNode(newNode);
        }
        this.count ++;
    }
    //获取链表大小
    public int size() {
        return this.count;
    }
    //判断链表是否为空
    public boolean isEmpty() {
        if (this.root == null && this.count == 0 ) {
            return false;
        } else {
            return true;
        }
    }
    //链表转换成对象数组
    public Object[] toArray() {
        if (this.count == 0) { //若是链表没有数据,那么就返回null
            return null;
        }
        this.retData = new Object[this.count];//若是count不为零,那么开辟指定空间的对象数组
        this.index = 0;//游标初始化为0
        this.root.toArrayNode();//交给Node类进行数据的取出
        return this.retData;//返回对象数组
    }
    //查找数据
    public boolean contains(Object search) {
        if (search == null || this.root == null) {
            return false;
        }
        return this.root.containsNode(search);
    }
    //根据索引取得数据
    public Object get(int searchIndex) {
        if (searchIndex >= this.count) {
            return null;
        }
        this.index = 0;
        return this.root.getNode(searchIndex);
    }
    //修改指定索引的数据
    public void setData(int searchIndex, Object newData) {
        if (searchIndex >= this.count) {
            return ;
        } else {
            this.index = 0;
            this.root.setNode(searchIndex, newData);
        }
    }
    //删除数据
    public void removeData(Object data) {
        if (this.contains(data)) {
            if (this.root.data.equals(data)) {
                this.root = this.root.next;
            } else {
                this.root.next.removeDataNode(this.root, data);
            }
            this.count --;
        }
    }
            
}
 
class Factory {
    public static Link getInstance() {
        return new Link();
    }
}
 
public class TestLinkDemo {
    public static void main(String[] args) {
        Link all = Factory.getInstance();
        //
        all.add("AAA");
        all.add("BBB");
        all.add("CCC");
        //
        System.out.println("链表大小为: " + all.size());
        //
        Object[] result = all.toArray();
        System.out.println("链表转换成对象数组并输出: ");
        for ( Object x : result ) {
            System.out.println(x);
        }
        //查询数据方法
        System.out.println("查询数据方法: ");
        System.out.println(all.contains("AAA"));
        System.out.println(all.contains("D"));
        //取得索引数据
        System.out.println("查找索引为0的数据: ");
        System.out.println(all.get(0));
        System.out.println("查找索引为3的数据: ");
        System.out.println(all.get(3));
        //修改索引数据
        System.out.println("修改索引数据: ");
        all.setData(0,"DDD");
        Object[] result1 = all.toArray();
        System.out.println("修改索引数据并输出: ");
        for ( Object x : result1 ) {
            System.out.println(x);
        }
        //删除数据
        System.out.println("删除数据: ");
        all.removeData("BBB");
        Object[] result2 = all.toArray();
        System.out.println("删除数据并输出: ");
        for ( Object x : result2 ) {
            System.out.println(x);
        }
    }
}

   


测试结果:this

相关文章
相关标签/搜索