链表类实现

简介:

  链表是一种最为基础的线性数据结构,在进行链表操作的时候使用若干个节点进行数据的存储,那么在进行数据存储的时候由于本身不具有排序的特点,所以在使用链表查询数据时,它的时间复杂度是“O(n)”,链表可以实现的优化解决方案使用跳表方案来完成,实际上和二分查找的意思相同,利用排序的模式,随机抽取几个中心点进行若干次的比较。

代码实现
/**
 * 定义链表接口
 * @param <T>
 */
interface ILink<T>{
    // 数据添加
    public void add(T data);
    // 获取数据个数
    public int size();
    // 判断链表是否为空
    public boolean isEmpty();
    // 数据转为对象数组
    public Object[] toArray();
    // 根据指定索引获取数据
    public T get(int index);
    // 修改数据 返回值:原始数据
    public T set(int index, T newData);
    // 查找链表中是否存在该数据
    public boolean contains(T data);
    // 删除数据
    public void remove(T data);
    // 清空链表
    public void clear();
}
/**
 * 实现类主要管理根节点
 * 内部类Node管理子节点
 * @param <T>
 */
class LinkImpl<T> implements ILink<T>{
    // 定义内部类
    private class Node<T>{
        private T data; // 保存数据
        private Node<T> next; // 引用,下一个数据的引用
        public Node(T data){
            this.data = data;
        }

        // 第1次调用方法:this = LinkImpl.root;
        // 第2次调用方法:this = LinkImpl.root.next;
        // 第3次调用方法:this = LinkImpl.root.next.next;
        public void addNode(Node<T> newNode){// 负责非根节点的节点关系
            if(this.next == null){// 当前节点之后有空余
                this.next = newNode;// 保存节点
            }else{
                this.next.addNode(newNode);
            }
        }

        public void toArrayNode(){
            LinkImpl.this.returnData[LinkImpl.this.foot++] = this.data;// 获取当前节点数据
            if(this.next != null){
                this.next.toArrayNode();// 递归调用
            }
        }

        public T getNode(int index){
            if(LinkImpl.this.foot++ == index){// 索引相同
                return this.data;// 返回当前数据
            }else{
                if(this.next != null){
                    return this.next.getNode(index);// 递归调用往下寻找
                }else{// 最后一个了
                    return null;
                }
            }
        }

        public T setNode(int index, T newData){
            if(LinkImpl.this.foot++ == index){// 找到索引了
                T temp = this.data;// 返回数据
                this.data = newData;// 修改数据
                return temp;// 返回原始数据
            }else{
                if(this.next != null){
                    return this.next.setNode(index, newData);
                }else{// 已经是最后一个数据了
                    return null;
                }
            }
        }

        public boolean containsNode(T data){
            if(this.data.equals(data)){// 数据判断相同
                return true;
            }else{
                if(this.next != null){// 往后查找
                    return this.next.containsNode(data);
                }else{// 最后一个返回false
                    return false;
                }
            }
        }

        /**
         * 删除数据
         * @param previous 删除数据的父节点
         * @param data 要删除的数据
         */
        public void removeNode(Node<T> previous, T data){
            if(this.data.equals(data)){
                previous.next = this.next;// 空出当前节点
            }else{
                if(this.next != null){// 还有后续节点
                    this.next.removeNode(this, data);// 递归调用
                }
            }
        }
    }

    private Node<T> root;// 根节点
    private int count;// 统计元素个数
    private int foot; // 索引脚标
    private Object[] returnData;// 返回数组

    /**
     * 实现添加数据
     * @param data
     */
    public void add(T data){
        if(data == null){// 排除掉所有的空元素
            return;
        }

        Node<T> newNode = new Node<T>(data);// 将数据封装在节点中
        if(this.root == null){ // 没有根节点
            this.root = newNode;// 第一个节点作为根节点
        }else{
            this.root.addNode(newNode);
        }
        this.count++;
    }
    /**
     * 实现数据的获取
     * @return
     */
    public int size(){
        return this.count;// 返回个数
    }
    /**
     * 判断链表是否为空实现
     * @return
     */
    public boolean isEmpty(){
        return this.size() == 0;
    }
    /**
     * 实现返回数据
     * @return
     */
    public Object[] toArray(){
        if(this.size() == 0){// 没有任何元素保存返回空
            return null;
        }
        this.foot = 0;// 脚标清零
        this.returnData = new Object[this.size()];
        this.root.toArrayNode();// 交由Node类负责处理
        return this.returnData;// 返回处理结果
    }
    /**
     * 根据索引获取数据实现
     * @param index
     * @return
     */
    public T get(int index){
        if(index >= this.size()){// 索引超过最大长度
            return null;
        }
        this.foot = 0;// 脚标清零
        return this.root.getNode(index);// 交由Node类完成
    }
    /**
     * 数据修改实现
     * @param index
     * @param newData
     * @return 原始数据
     */
    public T set(int index, T newData){
        if(index >= this.size()){// 索引超过最大长度
            return null;
        }
        this.foot = 0;// 脚标清零
        return this.root.setNode(index, newData);// 交由Node类完成
    }
    /**
     * 判断链表中是否有该数据实现方法
     * @param data
     * @return
     */
    public boolean contains(T data){
        if(this.size() == 0 || data == null){// 数据为空
            return false;
        }
        return this.root.containsNode(data);
    }
    /**
     * 删除数据实现
     * @param data
     */
    public void remove(T data){
        if(this.size() == 0 || data == null){
            return;
        }
        if(this.root.data.equals(data)) {// 删除数据为根节点
            this.root = this.root.next;// 修改根节点为根节点的下一节点
        }else{// 后续的判断可以从第2个节点开始
            if(this.root.next != null){
                this.root.next.removeNode(this.root, data);
            }
        }
        this.count --;
    }
    /**
     * 清空链表数据
     */
    public void clear(){
        this.root = null;//清空所有引用
        this.count = 0;
    }
}

/**
 * 测试类
 */
public class Test {
    public static void main(String[] args) {
        ILink<String> link = new LinkImpl<String>();
        System.out.println("-----------1.初始化的个数和状态-----------");
        System.out.println("数据保存前的个数"+ link.size());
        System.out.println("数据保存前是否为空"+ link.isEmpty());
        link.add("你");
        link.add("好");
        System.out.println("-----------2.保存后的个数和状态-----------");
        System.out.println("数据保存后的个数"+ link.size());
        System.out.println("数据保存后是否为空"+ link.isEmpty());
        System.out.println("-----------3.链表转数组-----------");
        System.out.print("数据遍历获取:");
        Object[] list = link.toArray();
        for (Object li : list){
            System.out.print(li+"、");
        }
        System.out.println();
        System.out.println("-----------4.获取索引-----------");
        System.out.println("获取索引为0的数据:"+link.get(0));
        System.out.println("获取索引为1的数据:"+link.get(1));
        System.out.println("获取索引为2的数据:"+link.get(2));
        System.out.println("-----------5.数据修改-----------");
        System.out.println("数据修改:"+link.set(0, "我")+" 修改后:"+link.get(0));
        System.out.println("-----------6.是否包含-----------");
        System.out.println("链表中是否有“你”:"+link.contains("你"));
        System.out.println("链表中是否有“我”:"+link.contains("我"));
        System.out.println("-----------7.删除-----------");
        link.remove("我");
        System.out.println("删除后的根节点:"+link.get(0));
        System.out.println("-----------8.清空链表-----------");
        link.clear();
        System.out.println("链表清空后的数据长度:"+link.size());
    }

执行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值