2.1线性表的链式存储——单链表(手工实现)

为了表示每个数据元素ai与其直接后继元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需要存储一个指示其直接后继的信息(即直接后继的存储位置)。我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称作指针或链。这两部分信息组成数据元素ai的存储映像,称为结点(Node)

n个结点链接在一起即为线性表的链式存储结构。

单链表

因为此链表的每个节点上都只有一个指针域指向后继结点,所以称为单链表

单链表指定位置添加结点时,首先我们要将目标链结点的next指针指向插入位置之后的链结点,之后还要使插入位置之前的链结点的next指针指向目标链结点。(注意顺序

单链表删除指定链结点,是通过将目标链结点的上一个链结点的next指针指向目标链结点的下一个链结点,示意图如下:

 手写单链表

类结构图

单链表封装类demo

package com.company.datastructure;
 
public class MySingleLinkedList<E> {
    //结点内部类
    private class Node<E> {
        public E element;  //默认初始化为null
        private Node<E> next;  //默认初始化为null
        public Node(){
 
        }
        public Node(E element){
            this.element = element;
        }
    }
    private Node<E> head;  //头结点
    private int size;  //元素总数
    //构造器(初始化链表)
    public MySingleLinkedList(){
        head = new Node<E>();  //默认初始化为null
    }
 
    //增加
 
    /**
     * 指定位置插入结点
     * @param index 索引
     * @param element 结点元素值
     */
    public void insert(int index,E element){
        rangeCheck(index);
        Node<E> newNode = new Node<E>(element);
        Node<E> temp = head;
        for (int i = 0; i < index; i++) {
            temp = temp.next;
        }
        newNode.next = temp.next;  //注意顺序
        temp.next = newNode;
        size++;
    }

    /**
     * 表头插入元素
     * @param element 结点元素值
     */
    public void addFirst(E element){
        Node<E> newNode = new Node<>(element);
        newNode.next = head.next;
        head.next = newNode;
        size++;
    }

    /**
     * 表尾插入元素
     * @param element 结点元素值
     */
    public void addLast(E element){
        Node<E> newNode = new Node<E>(element);
        Node<E> temp = head;
        while(temp.next!=null){
            temp = temp.next;
        }
        newNode.next = temp.next;  //注意顺序
        temp.next = newNode;
        size++;
    }
 
    //删除
 
    /**
     * 删除指定索引处元素(不包含头尾元素)
     * @param index 索引
     * @return 删除元素值
     */
    public E remove(int index){
        rangeCheck(index);
        Node<E> temp = head;
        for (int i = 0; i < index; i++) {
            temp = temp.next;
        }
        E oldElement = temp.next.element;
        temp.next = temp.next.next;
        size--;
        return oldElement;
    }


    /**
     * 从表头删除元素
     * @return 删除元素值
     */
    public E removeFirst() {
        if (size==0){
            throw new IndexOutOfBoundsException("链表为空");
        }
        E oldElement = head.next.element;
        head.next = head.next.next;
        size--;
        return oldElement;
    }

    /**
     * 从表尾删除元素
     * @return 删除元素值
     */
    public E removeLast(){
        if (size==0){
            throw new IndexOutOfBoundsException("链表为空");
        }
        Node<E> temp = head;
        while(temp.next.next!=null){
            temp = temp.next;
        }
        E oldElement = temp.next.element;
        temp.next = null;
        size--;
        return oldElement;
    }

    //修改
 
    /**
     * 修改指定索引处元素值
     * @param index 索引
     * @param element 元素值
     * @return 成功返回原元素值
     */
    public E set(int index,E element){
        rangeCheck(index);
        Node<E> temp = head;
        for (int i = 0; i < index; i++) {
            temp = temp.next;
        }
        Node<E> oldValue = temp.next;
        temp.next.element = element;
        return oldValue.element;
    }
    //查找
 
    /**
     * 根据索引返回元素值
     * @param index 索引
     * @return 索引处元素值
     */
    public E get(int index){
        rangeCheck(index);
        Node<E> temp = head;
        for (int i = 0; i < index; i++) {
            temp = temp.next;
        }
        return temp.next.element;
    }
    /*---------------------------------------------------------------------------------*/
    /**
     * 获得链表长度
     * @return 链表长度
     */
    public int size(){
        return size;
    }
 
    /**
     * 链表是否为空
     * @return true为空,false不为空
     */
    public boolean isEmpty(){
        return size==0?true:false;
    }
 
    /**
     * 清空链表
     */
    public void clear(){
        Node<E> temp = head;
        while(temp.next!=null){
            Node<E> next = temp.next;
            temp.element = null;
            temp.next = null;
            temp = next;
        }
        temp.element = null;
        size = 0;
    }
 
    /**
     * toString方法
     * @return 链表内容
     */
    public String toString(){
        if(size==0){
            return "[]";
        }else{
            Node<E> temp = head.next;
            StringBuilder sb = new StringBuilder("[");
            while(temp.next!=null){
                sb.append(temp.element+",");
                temp = temp.next;
            }
            return sb.append(temp.element).append("]").toString();
        }
    }
    /*---------------------------------------------------------------------*/
 
    /**
     * 索引检查
     * @param index 索引
     */
    private void rangeCheck(int index){
        if (index <0|| index >= size){
            throw new IndexOutOfBoundsException("索引不合法"+index);
        }
    }
}

单链表测试demo

package com.company.datastructure;
 
public class TestMySingleLinkedList {
    public static void main(String[] args) {
        MySingleLinkedList<Integer> msl = new MySingleLinkedList<>();
        msl.addLast(1);
        msl.addLast(3);
        msl.addLast(4);
        msl.insert(1,2);
        msl.addFirst(0);
        System.out.println(msl.size());
        System.out.println(msl);
        System.out.println(msl.get(1));
        int a = msl.remove(1);
        System.out.println(a);
        msl.removeFirst();
        msl.removeLast();
        System.out.println(msl.size());
        System.out.println(msl);

    }
}

猜你喜欢

转载自blog.csdn.net/weixin_39722922/article/details/86494958