什么是链表,手写一个LinkedList链表

什么是链表,手写一个LinkedList链表

不涉及泛型,存储的数据类型为int类型

1 认识链表

链表是一种数据结构,是线性表的一种,由一个个节点组成,节点中包括数据域和指针域

相比我们用的最多的一种数据结构——数组,数组可以存储一个固定大小的相同类型元素的顺序集合,所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。

两种结构均可实现数据的顺序存储,但是

  • 数组元素在栈区,链表元素在堆区

  • 数组在内存中连续,链表一般来说不连续,随机分配

  • 数组插入或者删除元素需要的时间长,而链表则只需要找到并增加或者删除

  • 数组大小是定义时分配好了,链表可以随着你的添加不断扩大。

2本篇涉及到的节点

请添加图片描述

对于一个集合来说,一般只需要存储size、first和last。而节点中需要prev,key,next。

于是我们的节点类和集合的基本属性和方法就确定下来了

public class IntegerNode {
    public Integer key;
    public IntegerNode prev;
    public IntegerNode next;

    public IntegerNode(IntegerNode prev,Integer key,IntegerNode next) {
        this.key=key;
        this.prev=prev;
        this.next=next;
    }

    @Override
    public String toString() {
        return "IntegerNode{" +
                "key=" + key +
                '}';
    }
}

public class FQLinkedList {
    IntegerNode first;
    IntegerNode last;
    int size = 0;

    public FQLinkedList() {
    }
}

3需要的方法

写的方法主要有以下这些

请添加图片描述

1 add方法

   /**
     *添加一个节点到末尾
     * @param integer:插入链表的节点中的值
     * @return
     */
    public boolean add(Integer integer){
        IntegerNode integerNode=new IntegerNode(last,integer,null);
        if(first==null){
            first=integerNode;
            last=first;
        }
        else {
            last.next=integerNode;
            last = integerNode;
        }
        size++;
        return true;
    }
    /**
     * 加到指定节点之前
     * @param integer:插入的值
     * @param integerNode:指定下标的节点
     */
    public void addBefore(int integer, IntegerNode integerNode){
        IntegerNode integerNode1 = new IntegerNode(integerNode.prev,integer,integerNode);
       if(integerNode.prev!=null) integerNode.prev.next = integerNode1;
       else first = integerNode1;
        integerNode.prev=integerNode1;
    }

有了以上两个方法一般的add都能实现

2clear方法

    /**
     *
     * 清空链表
     */
    public void clear(){
        for(IntegerNode x=first;x!=null;){
            IntegerNode c=x.next;
            x.prev=null;
            x.key=null;
            x.next=null;
            x=c;
        }
        size=0;
    }
  /**
     * 该方法也能清空链表
     */
    public void clear1(){
        first=last=null;
        size=0;
    }

在LinkedList源码中,关于clear方法是使用第一种方法,但是为什么不能使用第二种呢?

3contains方法

    /**
     * 返回对应元素所在链表的位置
     * @param x:要查询的元素
     * @return
     */
    public int indexOf(int x){
        int index=0;
        for(IntegerNode c=first;c!=null;c=c.next){
            if(c.key==x)return index;
            index++;
        }
        return -1;
    }
 /**
     * 判断链表是否包含该元素
     * @param x:指定一个元素
     * @return
     */
    public boolean contains(int x){
        if(indexOf(x)!=-1)return true;
        return false;
    }

4get方法

    /**
     * 获得指定下标节点的值
     * @param index:指定一个下标
     * @return
     */
    public int get(int index){
        return integerNode(index).key;
    }

5关于栈和队列


    /**
     * 将指定元素插入链表末尾
     * @param x:指定元素
     * @return
     */
    public boolean offer(int x){
        return add(x);
    }

    /**
     *返回第一个节点的值并移除它
     * @return
     */
    public int poll(){
        IntegerNode integerNode=first;
        first=first.next;
        first.prev=null;
        size--;
        return integerNode.key;
    }
    /**
     *从这个列表所表示的堆栈中弹出一个元素。
     */
    public int pop(){
        IntegerNode integerNode=last;
        last=last.prev;
        size--;
        return integerNode.key;
    }

    /**
     * 将一个元素推到由该列表表示的堆栈上。
     * @param x:指定元素
     */
    public void push(int x){
        addFirst(x);
    }

6替换,set方法

    /**
     * 将此列表中指定位置的元素替换为指定的元素。
     * @param index:指定下标
     * @param id:要更换的值
     * @return 返回更换的元素
     */
    public int set(int index,int id) {
        IntegerNode x = first;
        for (int i = 0; i < index; i++) x = x.next;
        x.key = id;
        return id;
    }
	/**
	 * 更换指定下标的元素
     * @param id:要更换的值
     * @return 返回更换的元素
     */
    public int set(int index,int id) {
        IntegerNode x = first;
        for (int i = 0; i < index; i++) x = x.next;
        x.key = id;
        return id;
    }

后记

其实对于写一个链表来说,我们最好先构思出父类要怎么写,从父类中抽象出各种集合所需要的共有的方法,其次再去构造子类集合

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值