LinkedList(1):链表介绍和单向链表的实现

1 链表介绍

链表的分类:单链表,双链表,循环链表

  • 链表:由链将一个个元素连接,每一个元素我们通常将其称之为Node 节点
  • Node 节点:由两部分组成

        数据值的变量

        Node next 用来存放下一个节点的Node 对象

package com.example.demo;

import java.util.LinkedList;

public class TestLinkedList {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList(); //双向链表
        linkedList.add(11);
        linkedList.add(22);
        linkedList.add(33);
        System.out.println(linkedList);
    }
}

LinkedList(1):链表介绍和单向链表的实现_第1张图片

  • 链表和数组的区别

        链表查询慢(因为链表没有索引),但是增删快,

 

2 自定义单向链表

设计接口

目的:为了体系的完整,以及代码的复用,设计出以下结构

需要实现的方法

public int size();
public boolean isEmpty();
public boolean contains(E element);
public void add(E element);
public E get(int index);
public E set(int index,E element);
public void add(int index, E element);
public E remove(int index);
public int indexOf(E element);
public void clear();
public String toStrin();

2.1 List 接口

包含共性的方法

package com.example.demo.dao;

// 将arryList 和LinkedList中共性方法进行抽取->保证体系的完整性
public interface List {
    int size();
    boolean isEmpty();
    boolean contains(E element);
    void add(E element);
    E get(int index);
    E set(int index,E element);
    void add(int index, E element);
    E remove(int index);
    int indexOf(E element);
    void clear();
    String toString();
}

2.2 AbstractList 抽象类

实现共性的方法,实现List

package com.example.demo.abstractclass;

import com.example.demo.dao.List;

public abstract class AbstractList implements List {
    protected int size;

    // 判断当前集合中是否有元素
    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void add(E element) {
        add(size,element);
    }
    //indexOf : 去寻找对应的元素,如果找到了返回元素的索引,如果没找到返回一个-1
    public boolean contains(E element) {
        return indexOf(element) != -1 ;
    }

}

2.3 LinkedList实现

顺序:

  • 定义结构
  • get -> node
  • indexOf(E element)
  • set(int index, E element)
  • clear()
  • add
  • remove
  • toString

package com.example.demo.Linked;

import com.example.demo.abstractclass.AbstractList;


public class LinkedList extends AbstractList {

    public Node first;

    private static class Node {
        Node next;
        E element;

        public Node(Node next, E element) {
            this.next = next;
            this.element = element;
        }
    }

    public E get(int index) {
        checkElementIndex(index);
        return node(index).element;
    }

    private void checkElementIndex(int index) {
        if (!isElementIndex(index)) {
            throw new IndexOutOfBoundsException(": Index: " + index + ", Size: " + size);
        }
    }

    private boolean isElementIndex(int index) {
        // 满足条件
        return index >= 0 && index < size;

    }

    private Node node(int index) {
        Node x = first;
        for (int i = 0; i < index; i++) {
            x = x.next;
        }
        return x;
    }


    public E set(int index, E element) {
        // 你在指定索引上去修改元素值是 element  ,原来返回原来的值
        checkElementIndex(index);
        Node node = node(index);
        //记录原来的老值
        E oldElement = node.element;
        //将传入的值进行覆盖
        node.element = element;
        return oldElement;
    }

    public void add(int index, E element) {
        checkPostionIndex(index); // 0   index >= 0
        // 1. 获得 index -1 的Node  同时 还要获得 index 节点  去改变index- 1 上的next ,同时去  将next 节点的内存值 赋值给 新new 出来的Node

        if (index == 0) {
            first = new Node(first, element);

        } else {
            Node pre = node(index - 1);
            Node next = pre.next;
            pre.next = new Node(next, element);
        }
        size++;
    }

    private void checkPostionIndex(int index) {
        if(!isPostionIndex(index)){
            throw new IndexOutOfBoundsException(": Index: " + index + ", Size: " + size);
        }
    }

    private boolean isPostionIndex(int index) {
        return index >= 0 && index <= size;
    }

    public E remove(int index) {
        checkElementIndex(index);
        Node oldNode = first;
        if(index == 0){
            first = first.next;
        }else {
            Node pre = node(index - 1);
            oldNode = pre.next;
            pre.next = oldNode.next;
        }
        return oldNode.element;
    }

    public int indexOf(E element) {
        Node x = first;
        int index = 0;
        if (element == null) {
            for (Node i = x; i != null; i = i.next) {
                if(element == i.element)
                {
                    return index;
                }
                index++;
            }

        } else {
            for (Node i = x; i != null; i = i.next) {
                if( element.equals(i.element)){
                    return index;
                }
                index ++;
            }
        }
        return -1;
    }

    public void clear() {
        size =0;
        first=null;
    }

    public String toString(){

        if(size == 0){
            return  "[]";
        }
        StringBuilder sb = new StringBuilder().append("[");
        Node x = first;
        for(Node i = x; i != null ; i = i.next){
            sb.append(i.element);
            if( i.next == null){
                return sb.append("]").toString();
            }
            sb.append(",");
        }
        return  sb.toString();
    }
}

2.4 测试结果如下

package com.example.demo;


import com.example.demo.Linked.LinkedList;

public class TestLinkedList {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList(); //双向链表
        linkedList.add(11);
        linkedList.add(22);
        linkedList.add(33);
        System.out.println(linkedList);
    }
}

你可能感兴趣的:(数据结构,链表,数据结构)