数据结构与算法-自定义双向链表API

Posted 闲言_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法-自定义双向链表API相关的知识,希望对你有一定的参考价值。

类名MyTowWayLinkeList
构造方法名public MyTowWayLinkeList()
成员内部类public class Node;结点类
成员方法public void insert(T t) ;往线性表添加一个元素
public void insert(int i,T t);在指定位置添加一个元素
public void clear();清空整个线性表;
public int length();获取线性表数据个数(长度)
public T remove(int index);删除指定索引处元素,并将其返回
public int indexOf(T t);获取该元素第一次出现的位序号
public boolean isEmpty();判断线性表是否为空
public T get(int index);获取线性表中指定位序号处的值
public T getFirst();获取线性表中头结点信息
public T getLast();获取线性表中尾结点信息
成员变量private int size;记录当前线性表的元素个数
private Node first;;定义头结点
private Node last;;定义尾结点
成员内部类变量private T item;用于存储数据
private Node next;用于存储下一个结点信息
private Node pre;用于存储上一个结点信息
代码如下
输出结果
线性表长度:5
判断线性表是否为空:false
获取线性表头结点信息:南慕容
获取线性表尾结点信息:段正淳
获取线性表位序号为1的结点信息:北乔峰
获取线性表位序号为2的结点信息:虚竹
获取线性表元素“北乔峰”第一次出现的索引:1
删除线性表序位号为4的元素是:虚竹
线性表长度:4
南慕容
北乔峰
段誉
段正淳
虚竹 

测试类

    public static void main(String[] args) {
        MyTowWayLinkeList<String> list = new MyTowWayLinkeList<>();
        list.insert("南慕容");
        list.insert("北乔峰");
        list.insert("虚竹");
        list.insert("段誉");
        list.insert("段正淳");

        System.out.println("线性表长度:" + list.length());
        System.out.println("判断线性表是否为空:" + list.isEmpty());
        System.out.println("获取线性表头结点信息:" + list.getFirst());
        System.out.println("获取线性表尾结点信息:" + list.getLast());
        System.out.println("获取线性表位序号为1的结点信息:" + list.get(1));
        System.out.println("获取线性表位序号为2的结点信息:" + list.get(2));
        System.out.println("获取线性表元素“北乔峰”第一次出现的索引:" + list.indexOf("北乔峰"));
        System.out.println("删除线性表序位号为4的元素是:" + list.remove(2));
        System.out.println("线性表长度:" + list.length());

        list.insert("虚竹");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

    }

MyTowWayLinkeList类

package cn.bloghut.linear;

import java.util.Iterator;

/**
 * @author by 闲言
 * @classname MyTowWayLinkeList
 * @description TODO
 * @date 2021/7/16 12:09
 */
public class MyTowWayLinkeList<T> implements Iterable {
    //记录元素个数
    private int size;
    //记录头结点信息
    private Node first;
    //记录最后一个结点信息
    private Node last;


    public class Node {
        //存储数据
        private T item;
        //指向下一个结点
        private Node next;
        //指向上一个结点
        private Node pre;

        /**
         * 初始化数据
         *
         * @param item
         * @param next
         * @param pre
         */
        public Node(T item, Node next, Node pre) {
            this.item = item;
            this.next = next;
            this.pre = pre;
        }
    }

    //初始化数据
    public MyTowWayLinkeList() {
        this.size = 0;
        this.first = new Node(null, null, null);
        this.last = new Node(null, null, null);

    }

    /**
     * 清空线性表
     */
    public void clear() {
        size = 0;
        first.pre = null;
        first.next = null;
        last.next = null;
        last.pre = null;
    }

    /**
     * 判断线性表是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 获取线性表元素个数
     *
     * @return
     */
    public int length() {
        return size;
    }

    /**
     * 返回线性表中第i个元素的值
     *
     * @param i
     * @return
     */
    public T get(int i) {
        //从头结点开始遍历
        Node node = first;
        for (int index = 0; index <= i; index++) {
            node = node.next;
        }
        return node.item;
    }

    /**
     * 在线性表中添加一个元素t
     */
    public void insert(T t) {
        //如果为空,说明是新创建的顺序表
        if (isEmpty()) {
            //创建新的结点
            Node newNode = new Node(t, null, first);
            //让新结点称为尾结点
            last = newNode;
            //让头结点指向尾结点
            first.next = last;
        } else {
            //如果链表不为空
            Node oldLast = last;
            //创建新的结点
            Node newNode = new Node(t, null, oldLast);
            //让当前的尾结点指向新结点
            oldLast.next = newNode;
            //让新结点称为尾结点
            last = newNode;
        }
        size++;
    }

    /**
     * 在线性表i位序处添加元素t
     *
     * @param i
     * @param t
     */
    public void insert(int i, T t) {
        //找到i位序的前一个结点
        Node pre = first;
        for (int index = 0; index < i; index++) {
            pre = pre.next;
        }
        //获取i位序的结点信息
        Node nextNode = pre.next;
        //创建新结点,该结点前驱指向i位序的前一个结点
        Node newNode = new Node(t, nextNode, pre);
        //让i位序的前一个结点的-后继指向新结点
        pre.next = newNode;
        //让i位序的结点的-前驱指向新结点
        nextNode.pre = newNode;
        //元素个数自增+1
        size++;
    }

    /**
     * 删除并返回线性表中第i个元素
     *
     * @param i
     * @return
     */
    public T remove(int i) {
        //从头结点开始遍历
        Node node = first;
        for (int index = 0; index < i; index++) {
            node = node.next;
        }
        //存储第i个元素数据
        Node oldNode = node.next;
        //存储第i个元素后面数据
        Node newNode = oldNode.next;
        //将第i个元素的后继指向   第i个原后面数据
        node.next = newNode;
        //将第i个元素 后面的元素 的 前驱指向 第i个元素 的前一个元素
        newNode.pre = node;
        //元素个数减1
        size--;
        return oldNode.item;
    }

    /**
     * 获取该运算第一次出现为位序号
     *
     * @param t
     * @return
     */
    public int indexOf(T t) {
        Node node = first;
        //从头结点开始遍历
        for (int i = 0; node.next != null; i++) {
            node = node.next;
            if (node.item.equals(t)) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取头结点数据
     *
     * @return
     */
    public T getFirst() {
        if (isEmpty()) {
            return null;
        }
        return first.next.item;
    }

    /**
     * 获取为结点数据
     *
     * @return
     */
    public T getLast() {
        if (isEmpty()) {
            return null;
        }
        return last.item;
    }

    @Override
    public Iterator iterator() {
        return new MyIterator();
    }

    /**
     * 自定义变量链表类
     */
    public class MyIterator implements Iterator {
        private Node node;

        public MyIterator() {
            this.node = first;
        }

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

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

以上是关于数据结构与算法-自定义双向链表API的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法-大集合

数据结构与算法系列五(双向链表)

数据结构与算法-自定义单向链表API

20120918-双向链表类定义《数据结构与算法分析》

数据结构与算法—— * 双向链表 *

尚硅谷算法与数据结构学习笔记03 -- 双向链表