数据结构三链表

链表定义

链表是一种物理存储单元上非连续,非顺序的存储结构。其物理结构不能直观的表示数据元素的逻辑顺序,数据元素的逻辑顺序是通过链表的指针连接顺序实现的。链表由一系列的结点组成,链表中的每一个元素称为结点,结点可以在运行时动态生成。

链表数据

插入数据

在结点A和结点B之间插入结点F,操作如下:

  1. 结点F的指针指向节点B 
  2. 结点A的指针指向结点F

删除数据

删除结点B的操作如下

  1. 结点A指针指向结点C。
  2. 结点B指针不在指向结点C。

结点类定义

结点API

类名Node
构造方法Node(T item, Node<T> next)
成员变量

T             item; // 存储数据

Node<T> next; //存储指针

 定义结点Node

@Data
public class Node<T> {
    private T item;

    private Node<T> next;

    public Node(T item, Node<T> next) {
        this.item = item;
        this.next = next;
    }
}

生成链表

public static void main(String[] args) {
        Node<String> aNode = new Node<>("A",null);
        Node<String> bNode = new Node<>("B",null);
        Node<String> cNode = new Node<>("C",null);
        Node<String> dNode = new Node<>("D",null);
        Node<String> gNode = new Node<>("G",null);

        aNode.next = bNode;
        bNode.next = cNode;
        cNode.next = dNode;
        dNode.next = gNode;
    }

单向链表

单向链表描述

单向链表是链表的一种,它有多个结点组成,每个结点都有一个数据域和一个指针域组成,数据域用来存储数据,指针域用来指向其后继结点。链表的头结点的数据域不存储数据,指针域指向第一个真正存储数据的结点。

单向链表API

类名LinkList
构造方法LinkList()
成员方法

public void clear()  //清空链表

public int size()  //链表长度

public boolean isEmpty()    //链表是否为空

public T get(int i)         //获取i位置的值
public void insert(T t)  //插入元素
public void insert(int i, T t) //在指定位置插入元素
public T remove(int i)   //移除指定位置的元素
public int indexOf(T t)   //查找元素的位置

成员内部类

private static class Node<T> 结点类

private class LIterator implements Iterator<T>

成员变量private Node<T> head;  //头结点
private int size;  //链表长度

单向链表实现 

import java.util.Iterator;

/**
 * 单向链表
 */
public class LinkList<T> implements Iterable<T> {

    /**
     * 头结点
     */
    private Node<T> head;

    /**
     * 链表长度
     */
    private int size;

    /**
     * 初始化链表
     */
    public LinkList() {
        head = new Node<T>(null, null);
        size = 0;
    }

    /**
     * 清空链表
     */
    public void clear() {
        this.head.next = null;
        this.size = 0;
    }

    /**
     * 链表长度
     */
    public int size() {
        return size;
    }

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

    /**
     * 获取i位置的值
     */
    public T get(int i) {
        if (i < 0 || i > size) {
            throw new RuntimeException("i位置错误");
        }

        if (isEmpty()) {
            throw new RuntimeException("LinkList is empty !");
        }

        Node<T> node = this.head.next;

        for (int index = 0; index < i; index++) {
            node = node.next;
        }

        return node.item;
    }

    /**
     * 插入元素
     */
    public void insert(T t) {
        Node<T> node = this.head;

        while (node.next != null) {
            node = node.next;
        }

        Node newNode = new Node(t, null);
        newNode.next = newNode;
        size++;
    }

    /**
     * 在指定位置插入元素
     */
    public void insert(int i, T t) {
        if (i < 0 || i > size) {
            throw new RuntimeException("i位置错误");
        }

        Node<T> pre = head;

        for (int index = 0; index <= i - 1; index++) {
            pre = pre.next;
        }

        Node currentNode = pre.next;
        Node<T> node = new Node<>(t, currentNode);

        pre.next = node;
        size++;
    }

    /**
     * 移除指定位置的元素
     */
    public T remove(int i) {
        if (i < 0 || i > size) {
            throw new RuntimeException("i位置错误");
        }

        Node<T> pre = head;
        for (int index = 0; i < i; index++) {
            pre = pre.next;
        }

        Node<T> currentNode = pre.next;
        pre.next = currentNode.next;
        size--;

        return currentNode.item;
    }

    /**
     * 查找元素的位置
     */
    public int indexOf(T t) {
        Node node = head;

        int i = -1;

        while (node.next != null) {
            node = node.next;
            i++;

            if (node.item.equals(t)) {
                return i;
            }
        }

        return i;
    }

    @Override
    public Iterator<T> iterator() {
        return new LIterator();
    }

    private class LIterator implements Iterator<T> {

        private Node<T> node;

        public LIterator() {
            node = head;
        }

        @Override
        public boolean hasNext() {
            return node.next != null;
        }

        @Override
        public T next() {
            return node.next.item;
        }
    }

    private static class Node<T> {
        private T item;

        private Node<T> next;

        public Node(T item, Node<T> next) {
            this.item = item;
            this.next = next;
        }

        public T getItem() {
            return item;
        }

        public void setItem(T item) {
            this.item = item;
        }

        public Node<T> getNext() {
            return next;
        }

        public void setNext(Node<T> next) {
            this.next = next;
        }
    }
}

双向链表

双向链表描述

双向链表也叫双向表,是链表的一种,它由多个结点组成,每个结点都有一个数据域 和 两个指针域组成,数据域用来存储数据,其中一个指针域用来指向其后继结点,另一个指针域用来指向前驱结点。链表的头结点的数据域不存储数据,指向前驱结点的指针域值为Null,指向其后继结点的指针指向第一个真正存储数据的结点。

 双向链表API

类名TwoWayLinkList
构造方法TwoWayLinkList()
成员方法

public void clear()  //清空链表

public int size()  //链表长度

public boolean isEmpty()    //链表是否为空

public T get(int i)         //获取i位置的值
public void insert(T t)  //插入元素
public void insert(int i, T t) //在指定位置插入元素
public T remove(int i)   //移除指定位置的元素
public int indexOf(T t)   //查找元素的位置

成员内部类

private static class Node<T> 结点类

private class LIterator implements Iterator<T>

成员变量

private Node<T> head;  //头结点

private Node<T> tail;    //尾结点
private int size;  //链表长度

代码实现 

/**
 * 单向链表
 */
public class TwoWayLinkList<T> implements Iterable<T> {

    /**
     * 头结点
     */
    private Node<T> head;

    /**
     * 头结点
     */
    private Node<T> tail;

    /**
     * 链表长度
     */
    private int size;

    /**
     * 初始化链表
     */
    public TwoWayLinkList() {
        head = new Node<T>(null, null, null);
        tail = null;
        size = 0;
    }

    /**
     * 清空链表
     */
    public void clear() {
        this.head.next = null;
        this.tail = null;
        this.size = 0;
    }

    /**
     * 链表长度
     */
    public int size() {
        return size;
    }

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

    /**
     * 获取i位置的值
     */
    public T get(int i) {
        if (i < 0 || i >= size) {
            throw new RuntimeException("i位置错误");
        }

        if(this.head.next == null){
            return null;
        }

        Node<T> currrent = this.head.next;

        for(int index = 0;index < i;index ++){
            currrent = currrent.next;
        }

        return currrent.item;
    }

    /**
     * 插入元素
     */
    public void insert(T t) {
        if (this.tail == null) {
            tail = new Node<>(t, head, null);
            head.next = tail;
        } else {
            Node<T> oldNode = tail;
            Node<T> newNode = new Node<>(t, head, oldNode);
            oldNode.next = newNode;
            this.tail = newNode;
        }

        size++;
    }

    /**
     * 在指定位置插入元素
     */
    public void insert(int i, T t) {
        if (i < 0 || i >= size) {
            throw new RuntimeException("i位置错误");
        }

        Node<T> pre = head;

        for (int index = 0; index <= i - 1; index++) {
            pre = pre.next;
        }

        Node currentNode = pre.next;
        Node<T> node = new Node<>(t,pre, currentNode);

        pre.next = node;
        currentNode.pre = node;
        size++;
    }

    /**
     * 移除指定位置的元素
     */
    public T remove(int i) {
        if (i < 0 || i >= size) {
            throw new RuntimeException("i位置错误");
        }

        if(isEmpty()){
            throw new RuntimeException("TwoWayLinkList is empty!");
        }

        Node<T> pre = head;
        for (int index = 0; index < i; index++) {
            pre = pre.next;
        }

        Node<T> currentNode = pre.next;
        Node<T> nextNode = currentNode.next;

        pre.next = nextNode;
        nextNode.pre = currentNode;

        size--;

        return currentNode.item;
    }

    /**
     * 查找元素的位置
     */
    public int indexOf(T t) {
        Node node = head;

        int i = -1;

        while (node.next != null) {
            node = node.next;
            i++;

            if (node.item.equals(t)) {
                return i;
            }
        }

        return i;
    }

    @Override
    public Iterator<T> iterator() {
        return new LIterator();
    }

    private class LIterator implements Iterator<T> {

        private Node<T> node;

        public LIterator() {
            node = head;
        }

        @Override
        public boolean hasNext() {
            return node.next != null;
        }

        @Override
        public T next() {
            return node.next.item;
        }
    }

    private static class Node<T> {
        private T item;

        private Node<T> pre;

        private Node<T> next;

        public Node(T item, Node<T> pre, Node<T> next) {
            this.item = item;
            this.pre = pre;
            this.next = next;
        }

        public T getItem() {
            return item;
        }

        public void setItem(T item) {
            this.item = item;
        }

        public Node<T> getNext() {
            return next;
        }

        public void setNext(Node<T> next) {
            this.next = next;
        }

        public Node<T> getPre() {
            return pre;
        }

        public void setPre(Node<T> pre) {
            this.pre = pre;
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值