您的位置 首页 java

数据结构之链表的简介

数据结构之链表的简介

(一)链表

  • ① 动态数组有个明显的缺点

可能会造成内存空间的大量浪费。

  • ② 能否用到多少就申请多少内存

添加新元素,就分配新的存储空间,用多少申请多少。 链表就可以办到这一点。

  • ③ 链表的定义

链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的。不按照顺序存储,所有的元素都是链式的,

链表存储,创建一个Node节点,Node节点的内部存储元素, 下一个Node的地址。来一个分配一个内存地址就可能不连续。地址肯定肯定是随机。一般最后的元素,提示的下一个Node的地址为null。

数据结构之链表的简介

数据结构之链表的简介

  • ④ 链表的设计

1.至少有2个东西:size存储元素的长度多少个节点,first指向第一个元素。
2.每个节点内部有2个元素:element,next ,element负责存储元素的数据,next服务指向下个元素的地址。
3.所有都是用到的时候才分配存储空间。

  • ⑤ 链表的接口
 package com.idig8;

public class LinkedList<E> {
    private int size;
    private Node<E> first;

    private static class Node<E>{
        E element;
        Node<E> next;
        public Node(E element,Node<E> next){
            this.element = element;
            this.next = next;
        }

    }
}  
  • ⑥ 抽出接口和父类

清空链表,添加获得链表个数,链表的长度,是否为空,获取链表,这些基本跟之前说的动态数组很类似,链表和动态数组都属于线性表,它们两个很多东西都是一样的很多时候可以直接想到的是继承。存一个一个问题,动态数组和链表它们添加,获取的方式都是不一样的,继承父类的话,它们暂且认为没有公共的代码,只是需要实现的功能一致,在java里面一般都是搞一个接口。接口有个特点只申明不实现,都有的接口进行申明。

接口

  public interface List {
   static final int ELEMENT_NOT_FOUND = -1;
   /**
  * 清除所有元素
  */void clear();
   /**
   * 元素的数量
   * @return
   */  int size();

  /**
   * 是否为空
   * @return
   */  boolean isEmpty();

  /**
   * 是否包含某个元素
   * @param element
   * @return
   */  boolean contains(E element);

  /**
   * 添加元素到尾部
   * @param element
   */  void add(E element);

  /**
   * 获取index位置的元素
   * @param index
   * @return
   */  E get(int index);

  /**
   * 设置index位置的元素
   * @param index
   * @param element
   * @return 原来的元素ֵ
   */  E set(int index, E element);

  /**
   * 在index位置插入一个元素
   * @param index
   * @param element
   */  void add(int index, E element);

  /**
   * 删除index位置的元素
   * @param index
   * @return
   */  E remove(int index);

  /**
   * 查看元素的索引
   * @param element
   * @return
   */  int indexOf(E element);
}  

一定会存在公共代码的问题,接口一般不只是一个地方使用,例如:List接口可以供ArrayList 和 LinkedList,对于他们公共的部分可以抽离出来,做一个抽象的父类。抽象类里面的接口有一部分可以不实现的,可以交给他下面的子类来进行实现。抽象类无法进行new,父类不对外公开,符合开发思路。

 public abstract class AbstractList<E> implements List<E>  {
    /**
     * 元素的数量
     */    protected int size;
    /**
     * 元素的数量
     * @return
     */    public int size() {
        return size;
    }

    /**
     * 是否为空
     * @return
     */    public boolean isEmpty() {
         return size == 0;
    }

    /**
     * 是否包含某个元素
     * @param element
     * @return
     */    public boolean contains(E element) {
        return indexOf(element) != ELEMENT_NOT_FOUND;
    }

    /**
     * 添加元素到尾部
     * @param element
     */    public void add(E element) {
        add(size, element);
    }

    protected void outOfBounds(int index) {
        throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
    }

    protected void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            outOfBounds(index);
        }
    }

    protected void rangeCheckForAdd(int index) {
        if (index < 0 || index > size) {
            outOfBounds(index);
        }
    }
}  

LinkedList 集成这个父类AbstractList

 public class LinkedList<E> extends AbstractList<E>{
    private Node<E> first;

    private static class Node<E>{
        E element;
        Node<E> next;
        public Node(E element,Node<E> next){
            this.element = element;
            this.next = next;
        }

    }
}  

PS:下次一起开始链表的代码讲解和实现。思考题:作为开发人员的你,上边这种抽象出来的思路,你应用的多吗,接口,抽象父类,子类继承父类的方式。

文章来源:智云一二三科技

文章标题:数据结构之链表的简介

文章地址:https://www.zhihuclub.com/180950.shtml

关于作者: 智云科技

热门文章

网站地图